概述

介绍

Spring Security使用接口SecurityContext抽象建模"安全上下文"这一概念。这里安全上下文SecurityContext指的是当前执行线程使用的最少量的安全信息(其实就是用于代表访问者账号的有关信息)。当一个线程在服务用户期间,该安全上下文对象会保存在SecurityContextHolder中。

SecurityContextHolder类提供的功能是保持SecurityContext,不过它的用法不是让使用者创建多个SecurityContextHolder对象,而是提供一组公开静态工具方法。基于这组方法,SecurityContextHolder主要提供了两种管理SecurityContext的模式 :

  1. 全局模式

    对整个应用公开保持一个SecurityContext,这种模式下,应用中的多个线程同一时间通过SecurityContextHolder访问到的都会是同一个SecurityContext对象;

  2. 线程本地模式

    对应用中的某个线程保持一个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 安全上下文相关推荐

  1. Spring Security 参考手册(一)

    Spring Security 参考手册 Ben AlexLuke TaylorRob WinchGunnar Hillert Spring security 是一个强大的和高度可定制的身份验证和访问 ...

  2. spring security面试题

    1.spring security所谓的全局上下文是如何实现的? ThreadLocal 2.了解spring security哪些核心组件,并介绍? AuthenticationManagerBui ...

  3. spring security logout(spring security登出示例)

    ** spring security logout(spring security登出示例) ** 在学习实现spring security登出的时候发现了一篇外文,感觉写的挺好,这里斗胆尝试翻译出来 ...

  4. 基于Spring Security与JWT实现单点登录

    基于RBAC的权限管理 RBAC(Role-Based Access Control):基于角色的访问控制 当前项目中,RBAC具体的表现为: 管理员表:ams_admin 角色表:ams_role ...

  5. Spring Security框架

    Spring Security框架 关于用户身份认证与授权 Spring Security是用于解决认证与授权的框架. 添加依赖 <!-- Spring Boot Security:处理认证与授 ...

  6. Java开发 - 单点登录初体验(Spring Security + JWT)

    目录​​​​​​​ 前言 为什么要登录 登录的种类 Cookie-Session Cookie-Session-local storage JWT令牌 几种登陆总结 用户身份认证与授权 创建工程 添加 ...

  7. Spring Security中的SecurityContext和SecurityContextHolder是什么?

    SecurityContext和SecurityContextHolder是Spring Security的两个基本类. SecurityContext用于存储当前经过身份验证的用户的详细信息,也称为 ...

  8. Spring Security + Spring Session Redis——【SecurityContext】和【AuthenticationToken】JSON反序列化问题解决方案

    前置 Spring Session + Redis--自定义JSON序列化解决方案 问题描述 Spring Security + Spring Session使用中Redis,默认序列化方式是JdkS ...

  9. 模拟Spring Security上下文进行单元测试

    今天,在为一种Java方法编写单元测试用例时,如下所示: public ApplicationUser getApplicationUser() {ApplicationUser applicatio ...

最新文章

  1. CentOS 部署 flask项目
  2. Redis + Tomcat + Nginx 集群实现 Session 共享
  3. js和html以及css的区别,html、css、js中的区别与关系
  4. Hbase完全分布式的搭建
  5. [Linux] ubuntu 格式化u盘
  6. 成功解决 shape = predictor(img, dets[0]) IndexError: Index out of range
  7. 技术解析系列 | PouchContainer volume机制解析
  8. 安装 深度wine_深度系统更新(2020.11.25)
  9. android audio 音量设置分析
  10. 虚拟机实时迁移解决方案
  11. 技术选型和知识点介绍(上)
  12. 记录团队日常工作清单用什么办公软件?
  13. 逆元的概念及求解方法
  14. x390拆机图解_Thinkpadx390详细拆机图解
  15. 【射频知识】吸波材料
  16. Python之Pickle学习
  17. python怎样删除某一行_python删除某一行
  18. “拆股”买投资房正在成为现实,不用攒钱也能买上房
  19. 3.python数据分析处理库pandas(学习笔记)
  20. vivado的使用技巧整理

热门文章

  1. 数据结构:(c实现)单向链表,单链表的头增,尾增,头删,尾删,任意位置的删除与插入。
  2. 零基础如何利用业余的时间学习数据分析
  3. HP加易语言数据库,全源码制作的网络验证,可运营,可自行扩展
  4. BZOJ1232 安慰奶牛cheer (洛谷2916)
  5. SpringBoot开发实用
  6. Spring Cloud Alibaba之Nacos
  7. Lambda表达式_Stream流_File类
  8. zdog+anime跳舞的小星星动画js特效
  9. 真无线蓝牙耳机什么便宜好用?五款口碑好的真无线蓝牙耳机
  10. HTML中alt标签的用法