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 ...
随机推荐
- 最顶尖的12个IT技能
这差不多是十年前得了,看看今天这些东西哪些死掉了,哪些成长茁壮了,又能有哪些启示. KevinScott是谷歌公司的高级技术经理,也是美国计算机协会专业与教育委 员会的创始成员,他说:“我在硅谷看到的 ...
- hdu 1.3.4 shǎ崽 OrOrOrOrz
简单的排序,注意输出即可 #include <iostream> #include <algorithm> using namespace std; int main() { ...
- 数独 php
数独求解程序 php版 转载请注明出处:http://xiezhenye.com/2008/06/%e6%95%b0%e7%8b%ac%e6%b1%82%e8%a7%a3%e7%a8%8b%e5% ...
- Flask restful API如何解决跨站请求问题
如果像下面这样只是在return的response添加header是不行的: response = make_response(jsonify(response=get_articles(ARTICL ...
- 【Java基础】反射和注解
前言 在Java中,反射机制和注解机制一直是一个很重要的概念,那么他们其中的原理是怎么样呢,我们不仅仅需要会使用,更要知其然而之所以然. 目录 反射机制 反射如何使用 注解定义 注解机制原理 注解如何 ...
- SpringBoot2 使用Spring Session集群
有几种办法: 1.扩展指定server利用Servlet容器提供的插件功能,自定义HttpSession的创建和管理策略,并通过配置的方式替换掉默认的策略.缺点:耦合Tomcat/Jetty等Serv ...
- [CTSC2008]网络管理(整体二分+树剖+树状数组)
一道经典的带修改树链第 \(k\) 大的问题. 我只想出三个 \(\log\) 的解法... 整体二分+树剖+树状数组. 那不是暴力随便踩的吗??? 不过跑得挺快的. \(Code\ Below:\) ...
- CuratorFramework使用
CuratorFrameworkFramework是ZooKeeper Client更高的抽象API 自动连接管理: 1. 当ZooKeeper客户端内部出现异常, 将自动进行重连或重试, 该过程对外 ...
- es6 学习小记 扩展运算符 三个点(...)
参考: es6 扩展运算符 三个点(...) 经常回顾,方能真正掌握. 一.含义 扩展运算符( spread )是三个点(...).它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列. ...
- 不同Mesh技术的比较-总结版
引言 在过去的几年里,Mesh 网络逐渐变得流行,随之会有越来越多的无线产品面世.Mesh 网络技术作为一种无线自组网技术是物联网的核心技术.物联网的概念现在也逐渐贴近人们的生活, 据预测 2011 ...