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 ...
随机推荐
- ★ prototype、__proto__ 详解
# var Person = function(name) { this.name = name; } var p = new Person(); //new操作符的操作是 var p = {} p. ...
- oracle 监听文件 说明
MAR:电脑笔记 不做整理 .. ORACLE_SID=orcl2 instance_name=sicca 静态注册文件中SID_NAME=ORACLE_SID 动态注册的时候是用的instance_ ...
- MySQL连接查询(多表查询)
基本含义 连接就是指两个或两个以上的表(数据源) “连接起来成为一个数据源”. 连接语法的基本形式:from 表1 [连接方式] join 表2 [on 连接条件]; 连接的结果可以当做一个“表”来使 ...
- poj3061
#include<stdio.h> #include<iostream> using namespace std; #include<algorithm> cons ...
- kafka_shell操作
单机版 开启进程: ./bin/kafka-server-start.sh config/server.properties 查看topic列表: ./bin/kafka-topics.sh --li ...
- codeforces 477D
题意:给定一个长度<=5000的二进制字符串S,以及一个初始为0的n,有一下两种操作: 1. 输出n(n>=1并且为2进制形式输出) 2.n=n+1 每次选择一种操作.. 求:1.有多少方 ...
- ASP.NET MVC Owin 基本理解
一.OWIN OWIN(Open Web Interface for .Net),定义了一个服务器(IIS)和Web应用程序(MVC,Webform)通信的标准接口,并且通过抽象层使得这两个在微软平台 ...
- Python自动化开发 - 函数
本节内容 函数背景介绍 函数是什么 参数与局部变量 返回值 递归函数 匿名函数 函数式编程介绍 高阶函数 一.函数背景介绍 老板让你写一个监控程序,监控服务器的系统状况,当cpu/memory/dis ...
- Linux查看History记录加时间戳小技巧
Linux查看History记录加时间戳小技巧 熟悉bash的都一定知道使用history可以输出你曾经输入过的历史命令,例如[root@servyou_web ~]# history | more ...
- Oracle PLSQL读取(解析)Excel文档
http://www.itpub.net/thread-1921612-1-1.html !!!https://code.google.com/p/plsql-utils/ Introduction介 ...