Spring Security : 概念模型 SecurityContext 安全上下文
概述
介绍
Spring Security
使用接口SecurityContext
抽象建模"安全上下文"这一概念。这里安全上下文SecurityContext
指的是当前执行线程使用的最少量的安全信息(其实就是用于代表访问者账号的有关信息)。当一个线程在服务用户期间,该安全上下文对象会保存在SecurityContextHolder
中。
SecurityContextHolder
类提供的功能是保持SecurityContext
,不过它的用法不是让使用者创建多个SecurityContextHolder
对象,而是提供一组公开静态工具方法。基于这组方法,SecurityContextHolder
主要提供了两种管理SecurityContext
的模式 :
- 全局模式
对整个应用公开保持一个
SecurityContext
,这种模式下,应用中的多个线程同一时间通过SecurityContextHolder
访问到的都会是同一个SecurityContext
对象; - 线程本地模式
对应用中的某个线程保持一个
SecurityContext
,这种模式下,应用中的每个线程同一时间通过SecurityContextHolder
访问到的都是关于自己线程的SecurityContext
;
SecurityContext
中保存的"最少量的安全信息"其实是通过Authentication
对象所携带的信息。它用于代表当前访问者。如果当前访问者尚未认证但正在认证,Authentication
内包含的是认证请求信息,比如用户名密码等等。如果当前访问者已经被认证,则Authentication
会包含更多当前访问者的信息,比如权限,用户详情等等。另外即使访问者一直在访问一些不需要登录认证的公开资源,也有可能存在Authentication
对象,此时Authentication
会是一种特殊的类型,专门用于表示这是一个匿名用户。
Spring Security
为接口SecurityContext
提供了一个缺省实现SecurityContextImpl
并在框架内各处缺省。
使用
// HttpServlet3RequestFactory 代码片段@Overridepublic void login(String username, String password) throws ServletException {// ...Authentication authentication;try {authentication = authManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));}catch (AuthenticationException loginFailed) {// 认证失败,清除 SecurityContextHolder 中的安全上下文SecurityContextHolder.clearContext();throw new ServletException(loginFailed.getMessage(), loginFailed);}// 认证成功,设置认证对象到 SecurityContextHolder 中的安全上下文SecurityContextHolder.getContext().setAuthentication(authentication);}@Overridepublic void logout() throws ServletException {LogoutHandler handler = HttpServlet3RequestFactory.this.logoutHandler;// ...Authentication authentication = SecurityContextHolder.getContext().getAuthentication();// 退出登录处理器也需要从 SecurityContextHolder 中获取安全上下文中的认证对象进行处理handler.logout(this, this.response, authentication);}
源代码
源代码版本 Spring Security Web 5.1.4.RELEASE
SecurityContext
接口
package org.springframework.security.core.context;import org.springframework.security.core.Authentication;import java.io.Serializable;/*** Interface defining the minimum security information associated with the current thread* of execution.** * The security context is stored in a SecurityContextHolder.* ** @author Ben Alex*/
public interface SecurityContext extends Serializable {// ~ Methods// ============================================================/*** Obtains the currently authenticated principal, or an authentication request token.** @return the Authentication or null if no authentication* information is available*/Authentication getAuthentication();/*** Changes the currently authenticated principal, or removes the authentication* information.** @param authentication the new Authentication token, or* null if no further authentication information should be stored*/void setAuthentication(Authentication authentication);
}
缺省实现 SecurityContextImpl
Spring Security为接口
SecurityContext提供的缺省实现
SecurityContextImpl,该实现逻辑其实很简单,主要就是保持一个
Authentication`对象。
package org.springframework.security.core.context;import org.springframework.security.core.Authentication;
import org.springframework.security.core.SpringSecurityCoreVersion;/*** Base implementation of SecurityContext.* * Used by default by SecurityContextHolder strategies.** @author Ben Alex*/
public class SecurityContextImpl implements SecurityContext {private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;// ~ Instance fields// ======================================================private Authentication authentication;public SecurityContextImpl() {}public SecurityContextImpl(Authentication authentication) {this.authentication = authentication;}// ~ Methods// ======================================================@Overridepublic boolean equals(Object obj) {if (obj instanceof SecurityContextImpl) {SecurityContextImpl test = (SecurityContextImpl) obj;if ((this.getAuthentication() == null) && (test.getAuthentication() == null)) {return true;}if ((this.getAuthentication() != null) && (test.getAuthentication() != null)&& this.getAuthentication().equals(test.getAuthentication())) {return true;}}return false;}@Overridepublic Authentication getAuthentication() {return authentication;}@Overridepublic int hashCode() {if (this.authentication == null) {return -1;}else {return this.authentication.hashCode();}}@Overridepublic void setAuthentication(Authentication authentication) {this.authentication = authentication;}@Overridepublic String toString() {StringBuilder sb = new StringBuilder();sb.append(super.toString());if (this.authentication == null) {sb.append(": Null authentication");}else {sb.append(": Authentication: ").append(this.authentication);}return sb.toString();}
}
参考文章
Spring Security : 概念模型 SecurityContext 安全上下文相关推荐
- Spring Security 参考手册(一)
Spring Security 参考手册 Ben AlexLuke TaylorRob WinchGunnar Hillert Spring security 是一个强大的和高度可定制的身份验证和访问 ...
- spring security面试题
1.spring security所谓的全局上下文是如何实现的? ThreadLocal 2.了解spring security哪些核心组件,并介绍? AuthenticationManagerBui ...
- spring security logout(spring security登出示例)
** spring security logout(spring security登出示例) ** 在学习实现spring security登出的时候发现了一篇外文,感觉写的挺好,这里斗胆尝试翻译出来 ...
- 基于Spring Security与JWT实现单点登录
基于RBAC的权限管理 RBAC(Role-Based Access Control):基于角色的访问控制 当前项目中,RBAC具体的表现为: 管理员表:ams_admin 角色表:ams_role ...
- Spring Security框架
Spring Security框架 关于用户身份认证与授权 Spring Security是用于解决认证与授权的框架. 添加依赖 <!-- Spring Boot Security:处理认证与授 ...
- Java开发 - 单点登录初体验(Spring Security + JWT)
目录 前言 为什么要登录 登录的种类 Cookie-Session Cookie-Session-local storage JWT令牌 几种登陆总结 用户身份认证与授权 创建工程 添加 ...
- Spring Security中的SecurityContext和SecurityContextHolder是什么?
SecurityContext和SecurityContextHolder是Spring Security的两个基本类. SecurityContext用于存储当前经过身份验证的用户的详细信息,也称为 ...
- Spring Security + Spring Session Redis——【SecurityContext】和【AuthenticationToken】JSON反序列化问题解决方案
前置 Spring Session + Redis--自定义JSON序列化解决方案 问题描述 Spring Security + Spring Session使用中Redis,默认序列化方式是JdkS ...
- 模拟Spring Security上下文进行单元测试
今天,在为一种Java方法编写单元测试用例时,如下所示: public ApplicationUser getApplicationUser() {ApplicationUser applicatio ...
最新文章
- CentOS 部署 flask项目
- Redis + Tomcat + Nginx 集群实现 Session 共享
- js和html以及css的区别,html、css、js中的区别与关系
- Hbase完全分布式的搭建
- [Linux] ubuntu 格式化u盘
- 成功解决 shape = predictor(img, dets[0]) IndexError: Index out of range
- 技术解析系列 | PouchContainer volume机制解析
- 安装 深度wine_深度系统更新(2020.11.25)
- android audio 音量设置分析
- 虚拟机实时迁移解决方案
- 技术选型和知识点介绍(上)
- 记录团队日常工作清单用什么办公软件?
- 逆元的概念及求解方法
- x390拆机图解_Thinkpadx390详细拆机图解
- 【射频知识】吸波材料
- Python之Pickle学习
- python怎样删除某一行_python删除某一行
- “拆股”买投资房正在成为现实,不用攒钱也能买上房
- 3.python数据分析处理库pandas(学习笔记)
- vivado的使用技巧整理