IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 实战,spring Boot security+JWT 前后端分离架构认证登录 -> 正文阅读

[Java知识库]实战,spring Boot security+JWT 前后端分离架构认证登录

前言

认证、授权是实战项目中必不可少的部分,而Spring Security则将作为首选安全组件,因此陈某新开了 《Spring Security 进阶》 这个专栏,写一写从单体架构到OAuth2分布式架构的认证授权。

Spring security这里就不再过多介绍了,相信大家都用过,也都恐惧过,相比Shiro而言,Spring Security更加重量级,之前的SSM项目更多企业都是用的Shiro,但是Spring Boot出来之后,整合Spring Security更加方便了,用的企业也就多了。

今天陈某就来介绍一下在前后端分离的项目中如何使用Spring Security进行登录认证。文章的目录如下:

前后端分离不同于传统的web服务,无法使用session,因此我们采用JWT这种无状态机制来生成token,大致的思路如下:

陈某使用的是Spring Boot 框架,演示项目新建了两个模块,分别是common-base、security-authentication-jwt。

1、common-base模块

这是一个抽象出来的公共模块,这个模块主要放一些公用的类,目录如下:

2、security-authentication-jwt模块

一些需要定制的类,比如security的全局配置类、Jwt登录过滤器的配置类,目录如下:

3、五张表

权限设计根据业务的需求往往有不同的设计,陈某用的RBAC规范,主要涉及到五张表,分别是用户表、角色表、权限表、用户<->角色表、角色<->权限表,如下图:

上述几张表的SQL会放在案例源码中(这几张表字段为了省事,设计的并不全,自己根据业务逐步拓展即可)

登录接口的逻辑写法有很多种,今天陈某介绍一种使用过滤器的定义的登录接口。

Spring Security默认的表单登录认证的过滤器是UsernamePasswordAuthenticationFilter,这个过滤器并不适用于前后端分离的架构,因此我们需要自定义一个过滤器。

逻辑很简单,参照UsernamePasswordAuthenticationFilter这个过滤器改造一下,代码如下:

上述的过滤器接口一旦认证成功,则会调用AuthenticationSuccessHandler进行处理,因此我们可以自定义一个认证成功处理器进行自己的业务处理,代码如下:

图片加载中…

陈某仅仅返回了accessToken、refreshToken,其他的业务逻辑处理自己完善。

同样的,一旦登录失败,比如用户名或者密码错误等等,则会调用AuthenticationFailureHandler进行处理,因此我们需要自定义一个认证失败的处理器,其中根据异常信息返回特定的JSON数据给客户端,代码如下:

图片加载中…

逻辑很简单,AuthenticationException有不同的实现类,根据异常的类型返回特定的提示信息即可。

AuthenticationEntryPoint这个接口当用户未通过认证访问受保护的资源时,将会调用其中的commence()方法进行处理,比如客户端携带的token被篡改,因此我们需要自定义一个AuthenticationEntryPoint返回特定的提示信息,代码如下:

AccessDeniedHandler这处理器当认证成功的用户访问受保护的资源,但是权限不够,则会进入这个处理器进行处理,我们可以实现这个处理器返回特定的提示信息给客户端,代码如下:

UserDetailsService这个类是用来加载用户信息,包括用户名、密码、权限、角色集合....其中有一个方法如下:

在认证逻辑中Spring Security会调用这个方法根据客户端传入的username加载该用户的详细信息,这个方法需要完成的逻辑如下:

我们需要实现这个接口,从数据库加载用户信息,代码如下:

其中的LoginService是根据用户名从数据库中查询出密码、角色、权限,代码如下:

UserDetails这个也是个接口,其中定义了几种方法,都是围绕着用户名、密码、权限+角色集合这三个属性,因此我们可以实现这个类拓展这些字段,SecurityUser代码如下:

拓展:UserDetailsService这个类的实现一般涉及到5张表,分别是用户表、角色表、权限表、用户<->角色对应关系表、角色<->权限对应关系表,企业中的实现必须遵循RBAC设计规则。这个规则陈某后面会详细介绍。

客户端请求头携带了token,服务端肯定是需要针对每次请求解析、校验token,因此必须定义一个Token过滤器,这个过滤器的主要逻辑如下:

上面只是最基础的一些逻辑,实际开发中还有特定的处理,比如将用户的详细信息放入Request属性中、Redis缓存中,这样能够实现feign的令牌中继效果。

校验过滤器的代码如下:

accessToken一旦过期,客户端必须携带着refreshToken重新获取令牌,传统web服务是放在cookie中,只需要服务端完成刷新,完全做到无感知令牌续期,但是前后端分离架构中必须由客户端拿着refreshToken调接口手动刷新。

代码如下:

主要逻辑很简单,如下:

注意:实际生产中refreshToken令牌的生成方式、加密算法可以和accessToken不同。

上述定义了一个认证过滤器JwtAuthenticationLoginFilter,这个是用来登录的过滤器,但是并没有注入加入Spring Security的过滤器链中,需要定义配置,代码如下:

所有的逻辑都在public void configure(HttpSecurity http)这个方法中,如下:

上述仅仅配置了登录过滤器,还需要在全局配置类做一些配置,如下:

完整配置如下:

注释的很详细了,有不理解的认真看一下。

1、首先测试登录接口,postman访问http://localhost:2001/security-jwt/login,如下:

可以看到,成功返回了两个token。

2、请求头不携带token,直接请求http://localhost:2001/security-jwt/hello,如下:

可以看到,直接进入了EntryPointUnauthorizedHandler这个处理器。

3、携带token访问http://localhost:2001/security-jwt/hello,如下:

成功访问,token是有效的。

4、刷新令牌接口测试,携带一个过期的令牌访问如下:

5、刷新令牌接口测试,携带未过期的令牌测试,如下:

可以看到,成功返回了两个新的令牌。

以上一系列的配置完全是参照UsernamePasswordAuthenticationFilter这个过滤器,这个是web服务表单登录的方式。

Spring Security的原理就是一系列的过滤器组成,登录流程也是一样,起初在org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter#doFilter()方法,进行认证匹配,如下:

attemptAuthentication()这个方法主要作用就是获取客户端传递的username、password,封装成UsernamePasswordAuthenticationToken交给ProviderManager的进行认证,源码如下:

ProviderManager主要流程是调用抽象类AbstractUserDetailsAuthenticationProvider#authenticate()方法,如下图:

retrieveUser()方法就是调用userDetailService查询用户信息。然后认证,一旦认证成功或者失败,则会调用对应的失败、成功处理器进行处理。

Spring Security虽然比较重,但是真的好用,尤其是实现Oauth2.0规范,非常简单方便。

每一篇文章都是精心输出,已经写了3个专栏,整理成PDF,可私信领取Java、spring、面试资料合集。

如果这篇文章对你有所帮助,或者有所启发的话,帮忙点赞、在看、转发、收藏,你的支持就是我坚持下去的最大动力!

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-12-06 15:07:02  更:2021-12-06 15:07:29 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 4:18:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码