spring-security jwt和权限配置实践

思君令人老,岁月忽已晚 。

1 前言

在前文中已经讲述了Spring-Security 认证流程分析及多方式登录认证实践,在本文中继续分享 spring-security 相关的内容。在项目开发中基本都是前后端分离的方式,通常使用 jwt 方式,上文已经讲述了登录认证的实践,本文将在此基础上继续进行权限配置的分享。

2 jwt

JWT 用于登录身份验证,用户成功登录后会根据用户信息生成一个 token 返回给客户端,其中包含用户信息,客户端每次请求都要在请求头 Authorization 上携带 token 信息,后端服务拿到 token 信息后,通过 secretKey 解密信息进行身份验证。JWT 生成的 Token 由三部分组成:

less 复制代码
JWT由三部分组成:header(头部)、payload(载荷)、signature(签名)
JWT的格式为:header.payload.signature, 都是通过 base64进行编码
header 
alg 指定 signature 采用的加密算法,默认是 HS256, 对称加密算法,也可以使用非对称加密算法 RS256
typ 固定值为 jwt
payload 
用户信息,令牌签发时间,令牌过期时间
signature
设置 secretkey, 将 header 和 payload 的结果进行合并,使用HS256算法合并计算
signature = HS256(baseUrl64(header)+'.'+baseUrl(payload)+','+secretKey)

上面介绍了 jwt 的结构,那怎么使用 jwt 生成 token, 并且怎么解析 token 呢,怎么判断 token 是否过期?首先我们需要先引入对应的依赖,如下所示:

xml 复制代码
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

创建 token 的方法以及解析 tokenjava 对象的方法如下图所示,在解析 token 时加入了其过期时间的判断,当 token 过期时会抛出自定义异常。

3 spring-security 整合 jwt

前文已经介绍了 jwt 的内容,结合 spring-security 来使用的话,首先需要创建一个过滤器,将其配置在 security 配置中。

创建过滤器如下所示,实践证明一下两者都可以,前者也是继承了后者,在其基础上增加了认证的内容:

arduino 复制代码
# spring-security 提供的认证拦截过滤器
BasicAuthenticationFilter
# spring 提供的过滤器 
OncePerRequestFilter

过滤器的任务便是从请求中获取 token 信息并进行解析,放入 Authentication 中并设置到 Security 上下文对象中,解析和验证 token 的流程使用 JwtUtils 提供的静态方法来完成。

如下图所示,即 security 的认证配置,在这里设置了两个登录地址,/login 使用 security 自带的登录认证方式,/login/user 使用自定义认证登录。前者使用 form 表单的方式进行登录认证在认证成功处理器中生成 token ,而自定义登录地址的方式在登录方法中生成 token , 两者都是通过 authenticate.getPrincipal() 的方式来获取用户信息。后者在功能扩展上十分方便。

两者的编码如下图所示:

4 权限配置

在 jwt 认证通过之后,就需要对登录用户赋予相应的角色和权限,以便用户查看各类权限的资源。通常情况下,一个用户会拥有多个角色,一个角色会拥有多个权限。具体如下图所示:

spring-securityspringboot 中的权限拦截是通过以下注解来实现的,都是使用在方法级别上:

less 复制代码
@PreAuthorize, 在方法请求之前进行鉴权
@PostAuthorize,在方法请求之后进行鉴权
@PreFilter, 过滤请求之前的集合参数
@PostFilter 过滤方法返回值,针对的是集合对象

通常情况下,使用的是 @PreAuthorize 注解,在方法之前之前进行鉴权。如下图所示,进行鉴权的方法有 has(Any)Role、 has(Any)Authority、 hasPermission 鉴权是通过 PermissionEvaluator 来处理的。

如下图所示,使用的是 @PreAuthorize,分别使用自带鉴权和自定义鉴权方法,自定义鉴权是通过角色来进行判断。自定义权限可以使用角色也可以使用权限,通常来说是通过权限来精细判断。

如果使用 spring-security 扩展权限认证时,需要重写 PermissionEvaluator,然后在配置中添加 DefaultWebSecurityExpressionHandler,如图右所示,采用这样的方式也可以设置角色的前缀,或者去掉前缀也可以。

相对而言,通过自定义的方式实现权限相对简单,实现方式如下图所示,可以不用实现接口 PermissionEvaluator,但是通过此种方法实现需要在使用时添加 @ 符号才能够生效。

三种方式的使用方式如下图所示,这里之所以能实现鉴权,是 spring-el 表达式来实现这样的鉴权方式。

6 总结

本文主要介绍了 spring security jwt 配置以及登录之后的鉴权,并以此为基础实践了多种方式的登录以及自定义鉴权,spring security 作为系统开发中常用的权限认证框架, jwt 方式在前后端分离项目中有着广泛的运用 。所涉及的代码已经上传至 gitee, 欢迎大家点赞关注。项目 gitee 地址 springsecurity-learn

相关推荐
千叶寻-26 分钟前
正则表达式
前端·javascript·后端·架构·正则表达式·node.js
小咕聊编程1 小时前
【含文档+源码】基于SpringBoot的过滤协同算法之网上服装商城设计与实现
java·spring boot·后端
追逐时光者8 小时前
推荐 12 款开源美观、简单易用的 WPF UI 控件库,让 WPF 应用界面焕然一新!
后端·.net
Jagger_8 小时前
敏捷开发流程-精简版
前端·后端
苏打水com9 小时前
数据库进阶实战:从性能优化到分布式架构的核心突破
数据库·后端
西瓜er9 小时前
JAVA:Spring Boot 集成 FFmpeg 实现多媒体处理
java·spring boot·ffmpeg
间彧10 小时前
Spring Cloud Gateway与Kong或Nginx等API网关相比有哪些优劣势?
后端
间彧10 小时前
如何基于Spring Cloud Gateway实现灰度发布的具体配置示例?
后端
间彧10 小时前
在实际项目中如何设计一个高可用的Spring Cloud Gateway集群?
后端
间彧10 小时前
如何为Spring Cloud Gateway配置具体的负载均衡策略?
后端