springboot成神之——basic auth和JWT验证结合
本文介绍basic auth和JWT验证结合
目录结构
依赖
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>auth0</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>auth0-spring-security-api</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20180813</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.xml.bind</artifactId>
<version>10.0-b28</version>
</dependency>
config配置文件WebSecurityConfig
package com.springlearn.learn.config;
import com.springlearn.learn.filter.JWTAuthenticationFilter;
import com.springlearn.learn.filter.JWTLoginFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configurers.provisioning.InMemoryUserDetailsManagerConfigurer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter implements WebMvcConfigurer {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable();
// 所有的请求都要验证
http.authorizeRequests()
.antMatchers("/").permitAll() // 访问 "/" 无需验证
.antMatchers(HttpMethod.POST, "/login").permitAll() // 访问 "/login" 无需token即可进入
.antMatchers(HttpMethod.GET, "/login").permitAll()
.anyRequest()
.authenticated()
.and()
.addFilterBefore( // 添加验证过滤器
new JWTLoginFilter("/login", authenticationManager()),
UsernamePasswordAuthenticationFilter.class
)
.addFilterBefore(
new JWTAuthenticationFilter(),
UsernamePasswordAuthenticationFilter.class
);
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
return bCryptPasswordEncoder;
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
String password = "234";
String encrytedPassword = this.passwordEncoder().encode(password);
System.out.println("Encoded password = " + encrytedPassword);
// 这里使用写死的验证,你可以在这里访问数据库
InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder> mngConfig = auth.inMemoryAuthentication();
UserDetails u1 = User.withUsername("yejiawei").password(encrytedPassword).roles("ADMIN").build();
UserDetails u2 = User.withUsername("donglei").password(encrytedPassword).roles("USER").build();
mngConfig.withUser(u1);
mngConfig.withUser(u2);
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*").allowedMethods("GET", "POST", "PUT", "DELETE").allowedOrigins("*")
.allowedHeaders("*");
}
}
filter过滤器JWTLoginFilter
package com.springlearn.learn.filter;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.stream.Collectors;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.springlearn.learn.service.TokenAuthenticationService;
import org.json.JSONObject;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter{
public JWTLoginFilter(String url, AuthenticationManager authManager) {
super(new AntPathRequestMatcher(url));
setAuthenticationManager(authManager);
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException, IOException, ServletException {
// get方式获取参数
// String username = request.getParameter("username");
// String password = request.getParameter("password");
// post方式获取数据
String s = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
JSONObject jsonObject = new JSONObject(s);
HashMap<String, String> result = new HashMap<String, String>();
String key = null;
Iterator<?> keys = jsonObject.keys();
while(keys.hasNext()) {
key = (String) keys.next();
result.put(key, jsonObject.getString(key));
}
System.out.printf("JWTLoginFilter.attemptAuthentication: username/password= %s,%s", result.get("username"), result.get("password"));
System.out.println();
return getAuthenticationManager().authenticate(new UsernamePasswordAuthenticationToken(result.get("username"), result.get("password"), Collections.emptyList()));
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
Authentication authResult) throws IOException, ServletException {
System.out.println("JWTLoginFilter.successfulAuthentication:");
// Write Authorization to Headers of Response.
TokenAuthenticationService.addAuthentication(response, authResult.getName());
String authorizationString = response.getHeader("Authorization");
System.out.println("Authorization String=" + authorizationString);
}
@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
response.setContentType("application/json");
response.setStatus(HttpServletResponse.SC_OK);
response.getOutputStream().println((new JSONObject(){{
put("status", 500);
put("message", "Internal Server Error!!!");
put("result", JSONObject.NULL);
}}).toString());
}
}
filter过滤器JWTAuthenticationFilter
package com.springlearn.learn.filter;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import com.springlearn.learn.service.TokenAuthenticationService;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.GenericFilterBean;
public class JWTAuthenticationFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
System.out.println("JWTAuthenticationFilter.doFilter");
Authentication authentication = TokenAuthenticationService.getAuthentication((HttpServletRequest) servletRequest);
SecurityContextHolder.getContext().setAuthentication(authentication);
filterChain.doFilter(servletRequest, servletResponse);
}
}
service中的TokenAuthenticationService
package com.springlearn.learn.service;
import java.io.IOException;
import java.util.Collections;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.JSONObject;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
public class TokenAuthenticationService {
static final long _expiretime = 864_000_000;
static final String _secret = "ThisIsASecret";
static final String _token_prefix = "Bearer";
static final String _header_string = "Authorization";
public static void addAuthentication(HttpServletResponse res, String username) throws IOException {
String JWT =
Jwts.builder()
.setSubject(username)
.setExpiration(new Date(System.currentTimeMillis() + _expiretime))
.signWith(SignatureAlgorithm.HS512, _secret).compact();
res.addHeader(_header_string, _token_prefix + " " + JWT);
res.setContentType("application/json");
res.setStatus(HttpServletResponse.SC_OK);
res.getOutputStream().println((new JSONObject(){{
put("status", 0);
put("message", "");
put("result", JWT);
}}).toString());
}
public static Authentication getAuthentication(HttpServletRequest request) {
String token = request.getHeader(_header_string);
if (token != null) {
// parse the token.
String user = Jwts.parser().setSigningKey(_secret).parseClaimsJws(token.replace(_token_prefix, "")).getBody()
.getSubject();
return user != null ? new UsernamePasswordAuthenticationToken(user, null, Collections.emptyList()) : null;
}
return null;
}
}
启动文件DemoApplication
package com.springlearn.learn;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Controller中的TestController
package com.springlearn.learn.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@ResponseBody
@RequestMapping(value = "/AuthTest", method = RequestMethod.GET)
public String AuthTest(HttpServletRequest request, HttpServletResponse response) {
return "OK";
}
@ResponseBody
@RequestMapping(value = "/login", method = RequestMethod.GET)
public String Login(@RequestBody Object user, HttpServletRequest request, HttpServletResponse response) {
return "OK";
}
}
前端测试
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
axios.post('http://localhost:9001/login', {
username: 'yejiawei',
password: '234'
}).then(function (response) {
localStorage.setItem("token", response.data.result)
}).catch(function (error) {
console.log(error);
}).then(function () {
});
// axios.get('http://localhost:9001/AuthTest', {
// headers: {
// "Authorization": localStorage.getItem("token")
// }
// }).then(function (response) {
// console.log(response.data);
// }).catch(function (error) {
// console.log(error);
// }).then(function () {
// });
</script>
</head>
<body>
</body>
</html>
springboot成神之——basic auth和JWT验证结合的更多相关文章
- springboot成神之——Basic Auth应用
本文介绍Basic Auth在spring中的应用 目录结构 依赖 入口DemoApplication 验证Authenication 配置WebSecurityConfig 控制器TestContr ...
- springboot成神之——ioc容器(依赖注入)
springboot成神之--ioc容器(依赖注入) spring的ioc功能 文件目录结构 lang Chinese English GreetingService MyRepository MyC ...
- springboot成神之——application.properties所有可用属性
application.properties所有可用属性 # =================================================================== # ...
- springboot成神之——springboot入门使用
springboot创建webservice访问mysql(使用maven) 安装 起步 spring常用命令 spring常见注释 springboot入门级使用 配置你的pom.xml文件 配置文 ...
- springboot成神之——mybatis和mybatis-generator
项目结构 依赖 generator配置文件 properties配置 生成文件 使用Example 本文讲解如何在spring-boot中使用mybatis和mybatis-generator自动生成 ...
- springboot成神之——swagger文档自动生成工具
本文讲解如何在spring-boot中使用swagger文档自动生成工具 目录结构 说明 依赖 SwaggerConfig 开启api界面 JSR 303注释信息 Swagger核心注释 User T ...
- springboot成神之——log4j2的使用
本文介绍如何在spring-boot中使用log4j2 说明 依赖 日志记录语句 log4j2配置文件 本文介绍如何在spring-boot中使用log4j2 说明 log4j2本身使用是非常简单的, ...
- springboot成神之——mybatis在spring-boot中使用的几种方式
本文介绍mybatis在spring-boot中使用的几种方式 项目结构 依赖 WebConfig DemoApplication 方式一--@Select User DemoApplication ...
- springboot成神之——发送邮件
本文介绍如何用spring发送邮件 目录结构 依赖 MailConfig TestController 测试 本文介绍如何用spring发送邮件 目录结构 依赖 <dependency> ...
随机推荐
- 有云Ceph课堂:使用CivetWeb快速搭建RGW
转自:https://www.ustack.com/blog/civetweb/ 优秀的开源项目正在改变传统IT,OpenStack名头最响,已经成为了IaaS的事实标准.Ceph同样颇有建树,通过其 ...
- iOS-沙盒路径
iphone沙箱模型的有四个文件夹,分别是什么,永久数据存储一般放在什么位置,得到模拟器的路径的简单方式是什么.documents,tmp,app,Library.(NSHomeDirectory() ...
- 探索Asp.net mvc 的文件上传
(转自:http://www.cnblogs.com/n-pei/archive/2010/10/15/1852635.html) 最近因为TeamVideo需要用到视频和图片上传功能,所以试着Goo ...
- mysql-debug: Thread stack overrun
bug info 报错信息: java.sql.SQLException: Thread stack overrun: 5456 bytes used of a 131072 byte stack, ...
- MySQL 5.7.3.0 安装 全程截图
前言: 下一个班快讲MySQL数据库了,正好把服务器里面的MySQL卸了重装了一下. 截个图,作为笔记.也正好留给需要的朋友们. 目录: 下载软件 运行安装程序 安装程序欢迎界面 许可协议 查找更新 ...
- php判断字符串长度 strlen()与mb_strlen()函数
PHP strlen() 函数 定义和用法 strlen() 函数返回字符串的长度. 语法 strlen(string) 参数:string <?php $str=‘中文a字1符‘; echo ...
- Android Framework 简介
Android Framework 简介 简介 之前的研究太偏向应用层功能实现了,很多原理不了解没有详记,结果被很多公司技术人员鄙视了,为了减少自己的短板,重新复习了一遍C++.java.Androi ...
- Android 静默安装/后台安装& Root permission
Android 静默安装/后台安装& Root permission 静默安装其实很简单,今天在网上找资料找半天都说的很复杂,什么需要系统安装权限.调用系统隐藏的api.需要系统环境下编译.需 ...
- Kali Linux ettercap的使用
ettercap是执行ARP欺骗嗅探的工具,通常用它来施行中间人攻击. 我还介绍过另一个arp欺骗工具-arpspoof 我使用的是Kali Linux 2.0:在开始使用ettercap之前,先配置 ...
- 【MFC】VC界面绘制双缓存
VC界面绘制双缓存 转载请注明原文网址: http://www.cnblogs.com/xianyunhe/archive/2011/11/20/2255811.html 1.闪屏的问题在GDI的绘图 ...