六、Spring Boot集成Spring Security之前后分离认证流程最佳方案
二、Spring Security默认认证流程及其优缺点
1、Spring Security默认认证流程总结
四、Spring Boot集成Spring Security之认证流程详细介绍了认证流程,其核心流程如下
- SecurityContextPersistenceFilter:chain.doFilter()前从安全上下文仓库中获取安全上下文,未登录状态时获取未认证的安全上下文;chain.doFilter()后从安全上下文持有者中获取安全上下文并更新到安全上下文仓库中
- LogoutFilter:如果是登出请求,清除安全上下文认证信息并重定向到登录页面,否则不处理
- UsernamePasswordAuthenticationFilter:如果是登录请求,校验请求参数中的用户名密码,校验成功后生成新的已认证的安全上下文并保存到安全上下文仓库中后重定向到目标URL,否则不处理
- DefaultLoginPageGeneratingFilter:如果是登录页面请求,返回默认登录页面,否则不处理
- DefaultLogoutPageGeneratingFilter:如果是登出页面请求,返回默认登出页面,否则不处理
2、优缺点
- 提供了完整的安全的认证流程
- 默认基于session实现非前后分离项目的认证流程,该流程已经慢慢退出历史舞台
- 未提供前后分离认证流程
三、前后分离项目认证思路
1、前后分离项目认证流程(基于默认流程优化)
- 前端输入用户名密码提交到后端
- 后端获取到用户名密码并校验,校验成功后生成token(类似于sessionId)返回给前端,生成已认证的安全上下文(类似于session)存储到安全上下文仓库中
- 前端获取到token,后续每次请求的请求头中都携带该token(类似于cookie)
- 后端获取请求头中的token,通过token获取安全上下文,并设置到安全上下文持有者中
- 前端提交退出请求时,后端获取请求头中的token,并通过token删除安全上下文仓库中安全上下文
2、前后分离项目认证流程关键组件对应的默认实现
从前后分离项目认证流程可以看出有四个关键组件
- 每次请求时通过请求头中token从安全上下文仓库中获取安全上下文的过滤器(默认SecurityContextPersistenceFilter)
- 登出时通过请求头中的token从安全上下文仓库中清除安全上下文的过滤器(默认LogoutFilter)
- 登录时验证用户名密码并生成token和安全上下文,将安全上下文添加到安全上下文仓库中的过滤器(默认UsernamePasswordAuthenticationFilter)
- 安全上下文仓库(默认HttpSessionSecurityContextRepository)
3、默认实现的局限性
- UsernamePasswordAuthenticationFilter从form表单中获取请求参数,不符合RESTFUL开发规范
- 认证的关键组件AuthenticationManager未注入到Spring容器中,导致自定义认证过滤器无法直接从Spring容器中获取
- UsernamePasswordAuthenticationFilter只实现了认证部分,认证成功后生成的安全上下文并添加安全上下文仓库中过程无法控制,只能使用默认的HttpSession或RequestAttributes方式,无法自定义
4、整改思路
- 自定义SecurityContextRepositoryImpl实现安全上下文仓库SecurityContextRepository,实现基于分布式缓存的安全上下文仓库
- 自定义RestfulUsernamePasswordAuthenticationFilter继承AbstractAuthenticationProcessingFilter,实现符合RESTFUL开发规范的登录方式
- 自定义UserDetailsImpl实现UserDetails接口,方便添加自定义属性
- 自定义UserDetailsServiceImpl实现UserDetailsService接口,实现基于数据库的认证方式,并生成token设置到UserDetails中
5、整改后的认证流程
- 前端输入用户名密码提交到后端
- 后端AbstractAuthenticationProcessingFilter调用子类RestfulUsernamePasswordAuthenticationFilter的attemptAuthentication方法获取认证信息
- RestfulUsernamePasswordAuthenticationFilter获取请求中的用户名密码,并调用UserDetailsService的loadUserByUsername获取用户信息
- UserDetailsServiceImpl通过用户名查询用户,将用户信息设置到创建的UserDetailsImpl对象中,生成token设置到UserDetailsImpl对象中
- AbstractAuthenticationProcessingFilter调用SecurityContextRepositoryImpl保存安全上下文
- SecurityContextRepositoryImpl获取安全上下文及其认证信息中的token,将token和安全上下文添加到分布式缓存中
- 将token返回到前端
- 前端获取token,每次请求时都在请求头中携带该token
- SecurityContextPersistenceFilter/SecurityContextHolderFilter调用SecurityContextRepositoryImpl的loadContext获取安全上下文
- SecurityContextRepositoryImpl获取请求头中token,使用token从分布式缓存中获取安全上下文并返回
- 前端提交登出请求
- LogoutFilter调用SecurityContextRepositoryImpl的saveContext,其中参数安全上下文为空值安全上下文
- SecurityContextRepositoryImpl判断出空值安全上下文,获取请求头中的token,使用token删除分布式缓存中获取安全上下文
四、总结
1、设计前后分离项目认证流程原则
- 尽可能贴合原生Spring Security处理流程,尽量使用Spring Security提供的组件
- 接口设计符合RESTFUL接口规范
- 使用分布式缓存存储登录凭证,更适合分布式项目
2、其他说明
- 这里说的前后分离项目认证流程最佳方案,是个人认为的最佳方案,并非行业公认的最佳方案,一千个读者就有一千个哈姆雷特,欢迎在评论区或者私信讨论你心中的最佳方案
- 下文代码实现该方案,敬请期待
六、Spring Boot集成Spring Security之前后分离认证流程最佳方案的更多相关文章
- Spring Boot集成Spring Data Reids和Spring Session实现Session共享
首先,需要先集成Redis的支持,参考:http://www.cnblogs.com/EasonJim/p/7805665.html Spring Boot集成Spring Data Redis+Sp ...
- SpringBoot系列:Spring Boot集成Spring Cache,使用EhCache
前面的章节,讲解了Spring Boot集成Spring Cache,Spring Cache已经完成了多种Cache的实现,包括EhCache.RedisCache.ConcurrentMapCac ...
- SpringBoot系列:Spring Boot集成Spring Cache,使用RedisCache
前面的章节,讲解了Spring Boot集成Spring Cache,Spring Cache已经完成了多种Cache的实现,包括EhCache.RedisCache.ConcurrentMapCac ...
- Spring Boot 集成 Spring Security 实现权限认证模块
作者:王帅@CodeSheep 写在前面 关于 Spring Security Web系统的认证和权限模块也算是一个系统的基础设施了,几乎任何的互联网服务都会涉及到这方面的要求.在Java EE领 ...
- Spring boot 集成Spring Security
依赖jar <dependency> <groupId>org.springframework.cloud</groupId> <artifactId> ...
- Spring Boot 集成spring security4
项目GitHub地址 : https://github.com/FrameReserve/TrainingBoot Spring Boot (三)集成spring security,标记地址: htt ...
- Spring boot集成spring session实现session共享
最近使用spring boot开发一个系统,nginx做负载均衡分发请求到多个tomcat,此时访问页面会把请求分发到不同的服务器,session是存在服务器端,如果首次访问被分发到A服务器,那么se ...
- Spring Boot 集成 Spring Security
1.添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...
- Spring Boot 集成 Spring Security 入门案例教程
前言 本文作为入门级的DEMO,完全按照官网实例演示: 项目目录结构 Maven 依赖 <parent> <groupId>org.springframework.boot&l ...
- Spring Boot 集成 Spring Security 使用自定义的安全数据源
编写一个类自定义实现 UserDetailsService 接口 @Service("customUserDetailService") public class CustomUs ...
随机推荐
- 十五分钟两百行代码,手写一个vue项目全局通用的弹框
前言: 我们在写vue项目时,弹框是非常常用的组件,并且在同一个项目中,弹框大多类似.所以我们可以抽离封装出一个通用的弹框: 因为vue3可向下兼容,所以作者这边会使用vue2的写法,vue3写法大同 ...
- 【Python自动化】之运用Git+jenkins集成来运行展示pytest+allure测试报告
目录: 一.安装allure 二.生成allure报告 三.结合jenkins来集成pytest+allure 四.结合Git集成Jenkins+Pytest+Allure测试报告 五.附录 一.安装 ...
- Echarts + 低代码 :可视化如何赋能企业的创新之路?
前言 数据驱动已经成为企业决策和业务优化的关键所在,在数字化时代,高效的数据分析与可视化呈现是实现智能决策的关键.利用低代码开发平台,企业可以快速构建满足业务需求的应用系统,实现对各类数据源的便捷接入 ...
- three.js的使用
以创建一个立方体为例 安装 安装three:npm i three 使用 引用 引入three以及three中自带的相机控件OrbitControls用以操控相机: 初始化场景 scene:场景所有t ...
- Dash 2.18版本新特性介绍
本文示例代码已上传至我的Github仓库:https://github.com/CNFeffery/dash-master Gitee同步仓库地址:https://gitee.com/cnfeffer ...
- 使用 nuxi init 创建全新 Nuxt 项目
title: 使用 nuxi init 创建全新 Nuxt 项目 date: 2024/9/6 updated: 2024/9/6 author: cmdragon excerpt: 摘要:本文介绍了 ...
- opencv equalizeHist
''' What are histograms? Histograms are collected counts of data organized into a set of predefined ...
- PYRAFORMER: 用于长时间序列建模和预测的低复杂度金字塔注意力《PYRAFORMER: LOW-COMPLEXITY PYRAMIDAL ATTENTION FOR LONG-RANGE TIME SERIES MODELING AND FORECASTING》(金字塔注意力模块机制、PAM、CSCM、多尺度)
今天是2022年10月1日,今天重读一遍这篇论文. 10月1日16:48,上次读是4月20日,时间过得好快. 论文:PYRAFORMER: LOW-COMPLEXITY PYRAMIDAL ATTEN ...
- ASP.NET Core – Globalization & Localization
前言 之前就写过 2 篇, 只是写的很乱, 这篇作为整理版. Asp.net core (学习笔记 路由和语言 route & language) Asp.net core 学习笔记之 glo ...
- Asp.net core 学习笔记之异常处理
自己写代码自己维护, 你爱怎样写都可以, 确保一致性就可以了. 不要自己写,自己看不懂 /.\ 但是如果有一天你要别人也看得懂...那就不单单是一致性的问题了,最好是用大众的 style. refer ...