Spring Boot使用JWT实现系统登录验证
简介
什么是JWT(Json Web Token)
jwt是为了在网络应用环境间传递声明而执行的一种基于json的开放标准。该token被设计紧凑且安全的,特别适用于SSO场景。
jwt的声明一般被用来在身份提供者和服务提供者之间传递被认证的用户身份信息。
JWT长什么样
eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZXN0MDAyIiwiZXhwIjoxNTEwOTcwMjU4fQ._FOqy5l44hODu3DjXh762LNUTLNQH15fdCUerdseDpmSKgkVSCjOyxQNTBKDSh3N-c83_pdEw5t6BdorgRU_kw
JWT的构成
JWT通常由三部分组成,头信息(header)、消息体(body)、签名(signature)
头信息指定了JWT使用的签名算法
header={alg=HS512}
消息体包含了JWT的意图,exp为令牌过期时间
body={sub=testUsername, exp=1510886546}
签名通过私钥生成
signature=kwq8a_B6WMqHOrEi-gFR5rRPmPL7qoShZJn0VFfXpXc1Yfw6BfVrliAP9C4UnXlqD3wRXO3mw_DDIdglN5lH9Q
使用springboot集成jwt
引用依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency> <dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>
构建普通rest接口
@RestController
@RequestMapping("/employee")
public class EmployeeController { @GetMapping("/greeting")
public String greeting() {
return "Hello,World!";
}
}
JwtLoginFilter
public class JwtLoginFilter extends UsernamePasswordAuthenticationFilter { private AuthenticationManager authenticationManager; public JwtLoginFilter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
} @Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
Employee employee = new Employee();
return authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
employee.getUsername(),
employee.getPassword(),
new ArrayList<>()
)
);
} @Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
FilterChain chain, Authentication authResult) throws IOException, ServletException {
String token = Jwts.builder()
.setSubject(((User) authResult.getPrincipal()).getUsername())
.setExpiration(new Date(System.currentTimeMillis() + 30 * 60 * 1000))
.signWith(SignatureAlgorithm.HS512, "JWTSecret")
.compact(); response.addHeader("Authorization", JwtUtils.getTokenHeader(token));
}}
JwtAuthenticationFilter
public class JwtAuthenticationFilter extends BasicAuthenticationFilter { public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
super(authenticationManager);
} @Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
String header = request.getHeader("Authorization"); if (header == null || !header.startsWith(JwtUtils.getAuthorizationHeaderPrefix())) {
chain.doFilter(request, response);
return;
} UsernamePasswordAuthenticationToken authenticationToken = getUsernamePasswordAuthenticationToken(header); SecurityContextHolder.getContext().setAuthentication(authenticationToken);
chain.doFilter(request, response);
} private UsernamePasswordAuthenticationToken getUsernamePasswordAuthenticationToken(String token) {
String user = Jwts.parser()
.setSigningKey("PrivateSecret")
.parseClaimsJws(token.replace(JwtUtils.getAuthorizationHeaderPrefix(), ""))
.getBody()
.getSubject(); if (null != user) {
return new UsernamePasswordAuthenticationToken(user, null, new ArrayList<>());
} return null;
}
}
SecurityConfiguration
@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override
public void configure(WebSecurity web) throws Exception {
super.configure(web);
} @Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable().authorizeRequests()
.anyRequest().authenticated()
.and()
.addFilter(new JwtLoginFilter(authenticationManager()))
.addFilter(new JwtAuthenticationFilter(authenticationManager()));
} }
使用postman测试
首先我们先测试/employee/greeting 响应如下:
{
"timestamp": 1510887634904,
"status": 403,
"error": "Forbidden",
"message": "Access Denied",
"path": "/employee/greeting"
}
很明显,状态码为403,此刻我们如果先登录拿到token后再测试呢,测试如下
登录成功后,我们可以看到headers中已经带有jwt
authorization →Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZXN0VXNlcm5hbWUiLCJleHAiOjE1MTA4ODkxMDd9.FtdEM0p84ff5CzDcoiQhtm1MF_NfDH2Ij1jspxlTQhuCISIzYdoU40OsFoxam9F1EXeVw2GZdQmArVwMk6HO1A
由于postman在一般情况下不支持自定义header 这个时候我们需要下载一个插件开启interceptor 开启后将authorization 放入header继续测试:
这时我们发现已经成功返回hello,world!
最后附上代码GitHub地址:源码下载
本文转载自
原文作者:胡运凡
Spring Boot使用JWT实现系统登录验证的更多相关文章
- Spring Boot 集成 JWT 实现单点登录授权
使用步骤如下:1. 添加Gradle依赖: dependencies { implementation 'com.auth0:java-jwt:3.3.0' implementation('org.s ...
- Spring Boot Security JWT 整合实现前后端分离认证示例
前面两章节我们介绍了 Spring Boot Security 快速入门 和 Spring Boot JWT 快速入门,本章节使用 JWT 和 Spring Boot Security 构件一个前后端 ...
- Spring Boot初识(4)- Spring Boot整合JWT
一.本文介绍 上篇文章讲到Spring Boot整合Swagger的时候其实我就在思考关于接口安全的问题了,在这篇文章了我整合了JWT用来保证接口的安全性.我会先简单介绍一下JWT然后在上篇文章的基础 ...
- thymeltesys-基于Spring Boot Oauth2的扫码登录框架
thymeltesys thymelte是一个基于Spring Boot Oauth2的扫码登录框架,使用PostgreSQL存储数据,之后会慢慢支持其他关系型数据库.即使你不使用整个框架,只使用其中 ...
- Spring Boot + Security + JWT 实现Token验证+多Provider——登录系统
首先呢就是需求: 1.账号.密码进行第一次登录,获得token,之后的每次请求都在请求头里加上这个token就不用带账号.密码或是session了. 2.用户有两种类型,具体表现在数据库中存用户信息时 ...
- Spring Boot 使用 JWT 进行身份和权限验证
上周写了一个 适合初学者入门 Spring Security With JWT 的 Demo,这篇文章主要是对代码中涉及到的比较重要的知识点的说明. 适合初学者入门 Spring Security W ...
- 实战!spring Boot security+JWT 前后端分离架构认证登录!
大家好,我是不才陈某~ 认证.授权是实战项目中必不可少的部分,而Spring Security则将作为首选安全组件,因此陈某新开了 <Spring Security 进阶> 这个专栏,写一 ...
- 基于Spring Boot的在线问卷调查系统的设计与实现+论文
全部源码下载 # 基于Spring Boot的问卷调查系统 ## 介绍 > * 本项目的在线问卷调查调查系统是基于Spring Boot 开发的,采用了前后端分离模式来开发. > * 前端 ...
- spring boot整合JWT例子
application.properties jwt.expire_time=3600000 jwt.secret=MDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjY34DFDSS ...
随机推荐
- 实战--利用SVM对基因表达标本是否癌变的预测
利用支持向量机对基因表达标本是否癌变的预测 As we mentioned earlier, gene expression analysis has a wide variety of applic ...
- spring boot jpa 多条件组合查询带分页的案例
spring data jpa 是一个封装了hebernate的dao框架,用于单表操作特别的方便,当然也支持多表,只不过要写sql.对于单表操作,jpake可以通过各种api进行搞定,下面是一个对一 ...
- noip第24课作业
1. 马走日 [问题描述] 马在中国象棋以日子形规则移动.请编写一段程序给定n*m大小的棋盘,以及马的初始位置(x,y),要求不能重复经过棋盘上的同一个点,计算马可以有多少途径遍历棋盘上的所有点. ...
- set_magic_quotes_runtime set_magic_quotes_gpc
set_magic_quotes_runtime(0); 可以修改php.ini中 magic_quotes_runtime boolean的设置 当你的数据中有一些\"'这样的字符要写入到 ...
- 3.java面向对象编程三大特性之多态
面向对象编程的三大特性:封装.继承.多态 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对类的外部而言它的内部实现细节是隐藏的,暴露给外界的只是它的实现方法. ...
- ASP.NET实现头像剪切保存
利用swfupload上传头像,利用Jcrop来实现头像在线选择,然后提交个ashx对原头像进行剪切.代码如下: default.aspx: <%@ Page Language="C# ...
- 修复msvcp120.dll
https://www.microsoft.com/zh-CN/download/details.aspx?id=40784
- Xcode一些好用的插件,以及这些插件的管理器
最近从xcode6.4升级到xcode7,发现以前所有的插件都失效了,如果要安装,需要重新去一个个下载.安装,很麻烦. 于是,转来了这篇博文,亲自测试,发现很好用...... 地址:http://11 ...
- 代码面试集锦 2 - Google
Given the root to a binary tree, implement serialize(root), which serializes the tree into a string, ...
- 【NumberValidators】工商营业执照号码和统一社会信用代码验证
从本质上讲,工商营业执照号码和统一社会信用代码是两套完全不一样的编码规则,识别结果也仅有行政区划部分为两者共有,但因为这两种编码同时存在的原因,所以如果需要在系统中唯一标志一家企业时,还是可以通过工商 ...