Spring Security与JWT
Spring Security
一. 权限控制
任何一个管理系统都必须要实现权限控制,它是任何一个系统的基础建设部分,以实现对公司不同岗位、不同角色员工的数据隔离。
在早期的权限控制使用的 ACL(Access Control List) 机制,它实现起来简单,对于使用者来说很麻烦,Linux操作系统就是这种机制,因为该操作系统能够使用的人很少。
现代的权限管理使用的是 RBAC(Role Based Access Control),基于角色的访问权限控制。就是给用户授予不同的角色,角色赋予不同的权限。它开发难度变大,但是使用简单。
二. 权限框架
在spring security诞生之前,业界使用的 shiro 这个权限框架,它可以不依赖与web容器和spring的IOC容器。Spring Security是必须要依赖web容器和spring的IOC容器。Spring security它作为 spring的亲儿子,从出生就备受关注,市场份额逐渐替代shiro。
Spring Security的学习难度要远远高于 shiro,但是我们按照一个简单的方式来实现权限控制。
三. 权限框架解决的问题
3.1 认证(Authentication)
认证就是解决 “我是谁” 的问题,就是用户是否可以访问该系统。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XsK2ZG8S-1677461821703)(images/authentication.jpg)]
3.2 授权(Authorization)
“授权” 表示用户进入系统只能,“能干什么”。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7U7UfFa1-1677461821704)(images/authorization.jpg)]
四. Springboot整合Security
第一步,导入如下的依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>
4.1 spring security的核心配置
/*** 1.@EnableWebSecurity 开启 spring secuirty的自定义配置*/
@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}// 关于 认证 和 授权的配置,都在该代码中实现@Overrideprotected void configure(HttpSecurity http) throws Exception {/*** 1. authorizeRequests() 方法的目的是为了配置哪些资源需要认证才能访问,哪些资源不需要认证就可以访问;* 2. authorizeRequests() 这个方法一旦被调用了,就会覆盖spring security内部的登录表单。*/http.authorizeRequests() //
// .antMatchers("/greet").permitAll() //permitAll() 可以不登录直接访问// /user/** 它可以匹配如下的路径: /user /user/add /user/add/a/b/c// authenticated() 表示对应的资源必须要认证了才能访问.antMatchers("/user/**", "/greet").authenticated() // ant 是spring中的一个路径匹配法则,“*” 表示匹配一个单词,“**” 是递归路径.antMatchers("/login").permitAll().and() // and() 方法表示的意思是,要做另外一个块的配置// .formLogin().disable() // 在前后端分离情况下,需要禁用spring security自带的登录功能.csrf().disable(); // csrf() 跨站伪造攻击,禁用掉;如果需要发送非 GET 请求,需要将 crsf() 禁用}
}
五. JWT
5.1 前后端分离的Session
下图为标准的session机制
在前后端分离的时候
5.2 JWT
JWT(Json Web Token),他就是一个字符串,它的出现是为了解决前后端分离登录的处理的。它分为3段,每一段之间是通过 “.” 来分割的,前两段其实就是一个 base64 的字符串,说白就是明文。它具有自验证的功能。
5.2.1 JWT的使用
第一步,需要引入如下的依赖
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-api</artifactId><version>0.11.2</version>
</dependency>
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-impl</artifactId><version>0.11.2</version><scope>runtime</scope>
</dependency>
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-jackson</artifactId> <!-- or jjwt-gson if Gson is preferred --><version>0.11.2</version><scope>runtime</scope>
</dependency>
第二步,jwt的生成
@Test
public void generateJWT() {// 密钥,需要绝对保密的一个字符串String key = "Qltw8l63IzprU54xLHTK3bzkY40iCLbA26Jo4IZmARXQALz0dBrclPDwkRyOUiDoasOioGtBAPfN0NWmrLC1Og==";/*** 将用于加密的字符串生成一个 Key 类型的对象*/Key k = new SecretKeySpec(Base64.getDecoder().decode(key), "HmacSHA512");// 生成一个 JWT的字符串String jwt = Jwts.builder().setSubject("admin") // 用户名信息,要放到的 payload.setIssuedAt(new Date()) // jwt的颁发日期.setExpiration(new Date(System.currentTimeMillis() + 2000)) // jwt的有效期.signWith(k, SignatureAlgorithm.HS512) // 生成jwt的算法.compact(); // 返回一个 jwt的字符串//System.out.println(jwt);
}
第三步,jwt的验证
@Test
public void verifyJWT() {// 一个jwt的字符串String jwt = "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiIsImlhdCI6MTY3Njk2Njk1NywiZXhwIjoxNjc2OTY2OTU5fQ.8Ub25SFQbP7K54VcoSD2Y_S9DXg6tXMisKgLuAk0Udcrl7hAZSvhFhIBfWt2I5DfssmH3lhV1wnukiqN2eKfMw";// 这是密钥,因为验证 JWT的时候,需要用当时生成的 jwt时候的密钥来进行验证String key = "Qltw8l63IzprU54xLHTK3bzkY40iCLbA26Jo4IZmARXQALz0dBrclPDwkRyOUiDoasOioGtBAPfN0NWmrLC1Og==";// 将密钥封装成一个 Key类型的对象Key k = new SecretKeySpec(Base64.getDecoder().decode(key), "HmacSHA512");/*** 如下的代码就是用来验证jwt的*/try {Claims claims = Jwts.parserBuilder().setSigningKey(k).build().parseClaimsJws(jwt).getBody();System.out.println("验证成功");}catch (Exception ex) {/*** 1. 如果抛出的是这个异常:SignatureException,jwt被篡改* 2. 如果抛出的是这个异常:MalformedJwtException,jwt被篡改了,格式不对。* 3. 如果抛出的是这个异常:ExpiredJwtException,jwt过期,需要重新登录。*/System.out.println(ex.getClass());}
}
第四步,jwt加密字符串的生成
@Test
public void generateKey() {Key key = Keys.secretKeyFor(SignatureAlgorithm.HS512);String k = new String(Base64.getEncoder().encode(key.getEncoded()));System.out.println(k);
}
补充
- 属性注入,在项目中非架构配置需要单独提取一个 properties 配置文件,例如如下的配置
jwt.jwt-token=Qltw8l63IzprU54xLHTK3bzkY40iCLbA26Jo4IZmARXQALz0dBrclPDwkRyOUiDoasOioGtBAPfN0NWmrLC1Og==
jwt.expire-time=2000000
/*** 第一种方式* 1.@PropertySource 作用是读取外部 properties 资源的* 2.关于配置,application.yml 是框架层面的配置,系统中业务数据不要往 application.yml 中配置*/
@PropertySource("classpath:app.properties")
@Component // 只有在容器中才能使用 @Value读取 配置文件中的内容
@Data
public class AppProperties {@Value("${jwt.jwt-token}")private String jwtToken;@Value("${jwt.expire-time}")private String expireTime;
}
/*** 1.获取配置文件的信息,这个方式用的比较多;* 2. @PropertySource 用来指定外部的 properties 配置文件;* 3. @ConfigurationProperties 用来指定将哪个前缀下的属性注入到该 Bean的属性中*/
@PropertySource("classpath:app.properties")
@Component
@ConfigurationProperties(prefix = "jwt") // prefix: 前缀 sufix: 后缀
@Data
public class AppProperties {private String jwtToken; // 配置文件中有两种写法:jwt-token 或者 jwtTokenprivate Long expireTime; // 配置文件中有两种写法:expire-time 或者 expireTime
}
prefix = “jwt”) // prefix: 前缀 sufix: 后缀
@Data
public class AppProperties {
private String jwtToken; // 配置文件中有两种写法:jwt-token 或者 jwtToken
private Long expireTime; // 配置文件中有两种写法:expire-time 或者 expireTime
}
Spring Security与JWT相关推荐
- Spring Security整合JWT,实现单点登录,So Easy~!
前面整理过一篇 SpringBoot Security前后端分离,登录退出等返回json数据,也就是用Spring Security,基于SpringBoot2.1.4 RELEASE前后端分离的情况 ...
- 【Spring】Spring Security OAuth2 JWT 认证
1.概述 Spring Security OAuth2 JWT 认证服务器配置 Spring Security OAuth2 JWT 资源服务器配置 Spring Security OAuth2 Re ...
- 学成在线-第16天-讲义- Spring Security Oauth2 JWT RSA加解密
学成在线-第16天-讲义- Spring Security Oauth2 JWT 1 用户认证需求分析 1.1 用户认证与授权 截至目前,项目已经完成了在线学习功能,用户通过在线学习页面点播视频进 ...
- 基于Spring Security和 JWT的权限系统设计
2019独角兽企业重金招聘Python工程师标准>>> 写在前面 关于 Spring Security Web系统的认证和权限模块也算是一个系统的基础设施了,几乎任何的互联网服务都会 ...
- Spring Security和 JWT两大利器来打造一个简易的权限系统。
写在前面 关于 Spring Security Web系统的认证和权限模块也算是一个系统的基础设施了,几乎任何的互联网服务都会涉及到这方面的要求.在Java EE领域,成熟的安全框架解决方案一般有 A ...
- 基于Spring Security与JWT实现单点登录
基于RBAC的权限管理 RBAC(Role-Based Access Control):基于角色的访问控制 当前项目中,RBAC具体的表现为: 管理员表:ams_admin 角色表:ams_role ...
- 【Spring Cloud Alibaba 实战 | 总结篇】Spring Cloud Gateway + Spring Security OAuth2 + JWT 实现微服务统一认证授权和鉴权
一. 前言 hi,大家好~ 好久没更文了,期间主要致力于项目的功能升级和问题修复中,经过一年时间这里只贴出关键部分代码的打磨,[有来]终于迎来v2.0版本,相较于v1.x版本主要完善了OAuth2认证 ...
- Spring Security Oauth2 JWT 实现用户认证授权功能
Spring Security Oauth2 JWT 一 用户认证授权 1. 需求分析 1.1 用户认证与授权 什么是用户身份认证? 用户身份认证即用户去访问系统资源时系统要求验证用户的身份信息,身份 ...
- SpringBoot 2 + Spring Security 5 + JWT 的单页应用 Restful 解决方案
此前我已经写过一篇类似的教程,但那时候使用了投机的方法,没有尊重 Spring Security 的官方设计,自己并不感到满意.这段时间比较空,故重新研究了一遍. 特性 使用 JWT 进行鉴权,支持 ...
- 使用Spring Boot和Spring Security验证JWT
对于我当前的项目,我将使用Spring Boot设置REST API (最有可能使用BoxFuse运行). 为了能够使用API端点,应用程序将检查传入的请求是否具有较早提供的有效JWT令牌 (由我 ...
最新文章
- P3952 时间复杂度(模拟)
- openresty总结
- android java11,Android RxJava1 入门教程
- 年度旗舰机广告片遭电视台泄露 三星:我有句话不知当讲不当讲
- QT每日一练day5:QLabel和按钮窗口打印功能
- 生鲜配送小程序源码_ThinkPHP社区水果生鲜蔬菜同城配送服务平台 社区团购商城小程序源码...
- 【ESD专题】案例:同样是RS485芯片,ESD的性能却天差地别?
- 2021年N1叉车司机最新解析及N1叉车司机模拟考试
- 【每日新闻】倪光南:“中国芯”切勿重硬轻软;美国研发出可直接在皮肤上打印的3D打印技术...
- 招聘网站分析-前程无忧网站的爬虫设计与实现
- 斑马标签打印机蛋疼的打印错误处理方法
- [Leetcode][分治法]相关题目汇总/分析/总结
- 移动网页支付(微信H5支付和支付宝网页支付)
- RSA算法实现(Python版)
- python安装cpickle_python中cPickle
- 安装Linux时报错This kernel requires an X86-64 CPU
- idea中打开有冲突的文件,解决冲突
- 汽车理论matlab编程,汽车理论课后作业matlab编程详解(带注释)
- 2009年世界顶级杀毒软件排名
- oracle数据泵的学习
热门文章
- OSCache 缓存重建在 Race Condition 下的 NRE 问题
- 峰度(Kurtosis)与偏态(Skewness)
- Learning with Noisy Label
- 处理日常事务的 Linux 程序和它们的配置
- 深入理解Java中的String(原地址https://www.cnblogs.com/xiaoxi/p/6036701.html)
- API Gateway技术设计
- 昆山有python培训吗
- 如何在Windows中查询证书颁发机构已颁发的证书
- 笔记本开WIFI简易批处理
- Windows使用腾讯云GPU跑深度学习