网站首页 > 技术文章 正文
若依框架中登录认证使用的是SpringSecurity安全管理框架,这个框架想必很多JAVA开发的朋友是比较熟悉的了,就算没有用过也听过,它和另外一个安全管理框架Shiro是java web开发中安全管理方案中常用的两个框架。若依并不会自己再去造一个轮子做权限管理,它也是直接集成了SpringSecurity这个框架,其实在若依中对SpringSecurity的配置比较简单,正是因为简单,所以本文就以若依为例子,一步一步带大家详细的了解SpringSecurity框架在项目中的应用
SpringSecurity整体上其实就是有两大模块,分别是认证和鉴权。为了实现这两个功能, SpringSecurity内部有一系列的组件,正是这些组件可以让SpringSecurity配置起来既简单又灵活。磨刀不误砍柴工,在剖析若依的认证原理之前,首先大概了解一下SpringSecurity的几个重要组件。
AuthenticationManager 认证管理器
SecurityContextHolder 安全上下文,可以理解成线程变量,底层就是基于ThreadLocal实现。
Authentication 认证结果接口
PasswordEncoder 密码编码器
UserDetailsService 用户认证接口
UserDetails 用户对象接口
AccessDeniedHandler 授权失败处理器
AuthenticationEntryPoint 认证失败处理器
LogoutSuccessHandler 退出成功处理器
了解完这些组件后,我们先看一下若依中对于用户认证这一部分的流程:
按这个流程图,我们一步一步看代码中是如何使用SpringSecurity实现用户认证的。首先看若依中对SpringSecurity的配置,在ruoyi-framework中的SecurityConfig.java这个配置类:
- 配置认证失败回调
- 配置鉴权失败回调
- 配置退出登录成功回调
- 配置jwt token验证过滤器
- 配置跨域过滤器
- 配置退出过滤器
- 配置密码编码器
- 配置自定义用户认证服务
- 配置认证密码编码器
其中2、5、6、7 是最核心的,这些组件都有各自的具体实现。接着我们看框架中是如何进行认证的。首先认证肯定就需要登录,所以入口肯定在登录的地方开始。
这个是登录的入口代码,登录成功后给前端返回一个token,接着往下看 loginService.login 这个方法的具体实现:
箭头部分就是具体的认证,这里就是使用SpringSecurity框架的认证服务入口。这一句代码看起来很简单,其实内部是各种接口委托完成的,我梳理了大概流程是这样的:
1、AuthenticationManager.authenticate() 内部会委托 ProviderManager.authenticate()
2、ProviderManager 内部又委托 AuthenticationProvider.authenticate()
3、AuthenticationProvider 的实现类 AbstractUserDetailsAuthenticationProvider 实现了认 authenticate接口,并新定义了两个抽象方法retrieveUser和additionalAuthenticationChecks 供子类去实现。
4、DaoAuthenticationProvider 继承了 AbstractUserDetailsAuthenticationProvider 并重写了其两个抽象方法retrieveUser,additionalAuthenticationChecks,其中retrieveUser内部又委托 UserDetailsService.loadUserByUsername 实现认证返回UserDetails
5、用户自定义UserDetailsService接口实现
按照这个流程,再继续往下看源码截图
ProviderManager 接口定义
AbstractUserDetailsAuthenticationProvider是一个抽象类,实现了ProviderManager
- retrieveUser 进行用户验证
- additionalAuthenticationChecks进行密码验证
DaoAuthenticationProvider部分代码
- 设置默认密码编码器
- 实现密码匹配
DaoAuthenticationProvider 继承 AbstractUserDetailsAuthenticationProvider 重写父类两个抽象方法。箭头地方委托 UserDetailsService.loadUserByUsername() 实现具体的认证逻辑
最终这个UserDetailsServiceImpl就是若依自定义的UserDetailsService接口实现类,主要逻辑就是验证用户是否存在数据库中,没有则抛出异常,否则返回一个UserDetails对象。密码验证则在 AbstractUserDetailsAuthenticationProvider中已经有默认实现。若依中LoginUser就是实现了UserDetails接口的类
上面就是SpringSecurity的认证逻辑过程,可以看到最终需要调用UserDetailsServiceImpl这个自己实现的类,因为在这个类里面可以根据用户名查询数据库用户是否存在从而完成真正的认证。通过框架认证成功后,最终返回LoginUser(其实就是UserDetails),接下来就是需要应用端自行保存这个用户信息了。
这里就是使用这个认证通过的用户创建一个jwt token返回给前端
creareToken这个方法主要有三个逻辑:
- 生成一随机唯一id
- 以这个id为key,将整个LoginUser对象存储到redis中(refreshToken方法)
- 正常创建token,token中的信息载体为第一步生成的id号
接着往下看 refreshToken方法
可以看到,设置失效时间后,将整个对象存入到redis中。接下来,就可以通过过滤器进行token的刷新了。在若依中是在 JwtAuthenticationTokenFilter 这个过滤器实现的
- 根据请求头获取当前token,通过token从redis中获取当前用户
- 验证当前用户是否快要过期则刷新过期时间
- 将当前用户设置到当前线程中,供后续的过滤器使用
到这里,若依中的用户认证具体实现就全部剖析完了,整个代码的实现其实也很简单,只不过若依对这个token做了一个封装以redis作为存储。认证通过后,接下来就是鉴权了,因为篇幅有限,下期和大家继续分享若依中是如何基于SpringSecurity实现用户鉴权的。
创作不易,如果觉得文章对你有用,请麻烦动动您灵活的手指点赞关注!
猜你喜欢
- 2024-09-29 Spring Security 自定义登录过程(非前后端分离版本)
- 2024-09-29 基于spring-security图形验证码、token验证
- 2024-09-29 10分钟上手SpringSecurity 框架(3)
- 2024-09-29 SpringBoot 实现自动登录时的安全风险控制
- 2024-09-29 springboot+security框架整合 springboot security详解
- 2024-09-29 时序图说明JWT用户认证及接口鉴权的细节
- 2024-09-29 Spring Security 整合OAuth2 springsecurity整合oauth2+jwt+vue
- 2024-09-29 有关springboot + spring security的思考
- 2024-09-29 SpringSecurity之自定义用户权限信息的存取
- 2024-09-29 你还不了解SpringSecurity吗?快来看看SpringSecurity实战总结
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)