zoukankan      html  css  js  c++  java
  • Spring Security -- SecurityContextHolder 详解

    前言

    SecurityContextHolder 按字面意思理解,就是安全上下文支持。在使用了 Spring Security 的 Spring Boot 应用中,我们在后端想要获取登录用户的信息,可以使用命令:

    SecurityContextHolder.getContext().getAuthentication().getPrincipal()
    

    源码分析

    这里调用了方法.getContext(),打开 SecurityContextHolder 的源码,部分源码如下

    public class SecurityContextHolder {
        public static final String MODE_THREADLOCAL = "MODE_THREADLOCAL";
        public static final String MODE_INHERITABLETHREADLOCAL = "MODE_INHERITABLETHREADLOCAL";
        public static final String MODE_GLOBAL = "MODE_GLOBAL";
        public static final String SYSTEM_PROPERTY = "spring.security.strategy";
        private static String strategyName = System.getProperty("spring.security.strategy");
        private static SecurityContextHolderStrategy strategy;
        private static int initializeCount = 0;
        
        ...
    
        private static void initialize() {
            if (!StringUtils.hasText(strategyName)) {
                strategyName = "MODE_THREADLOCAL";
            }
    
            if (strategyName.equals("MODE_THREADLOCAL")) {
                strategy = new ThreadLocalSecurityContextHolderStrategy();
        ...
    
        public static SecurityContext getContext() {
            return strategy.getContext();
        }
        ...
    

    可以看到,方法.getContext()来源于 SecurityContextHolderStrategy ,再打开 SecurityContextHolderStrategy 的源码:

    package org.springframework.security.core.context;
    
    public interface SecurityContextHolderStrategy {
        void clearContext();
    
        SecurityContext getContext();
    
        void setContext(SecurityContext var1);
    
        SecurityContext createEmptyContext();
    }
    

    可知 SecurityContestHolderStrategy 只是一个接口,这个接口提供创建、清空、获取、设置上下文的操作。

    那它有哪些实现类呢,也就是有哪些存储策略呢?按住 Ctrl + H,查看它的实现类,如下图:

    可以看出,SecurityContestHolderStrategy 有三个实现类,分别是

    1. ThreadLocalSecurityContextHolderStrategy

    2. GlobalSecurityContextHolderStrategy

    3. InheritableThreadLocalSecurityContextHolderStrategy

    就跟字面意思一样三种策略分别对应 threadlocal,global,InheritableThreadLocal 三种方式。

    SecurityContextHolder 默认使用的是 ThreadLocalSecurityContextHolderStrategy 安全策略。

    也就是说,方法.getContext()在接口SecurityContestHolderStrategy中定义,在类 ThreadLocalSecurityContextHolderStrategy 中实现的。

    然后是方法.getAuthentication(), 按 Ctrl + 鼠标左键,打开源码:

    public interface SecurityContext extends Serializable {
        Authentication getAuthentication();
    
        void setAuthentication(Authentication var1);
    }
    

    接口 SecurityContext 只有 getAuthenticationsetAuthentication 这两个方法,而这两个方法都是 Authentication 类型。

    由源码可知,所谓的安全上下文,只是保存了 Authentication(认证信息),在 Spring Security 使用一个 Authentication 对象来表示这些用户信息。

    打开 Authentication 的源码:

    public interface Authentication extends Principal, Serializable {
        Collection<? extends GrantedAuthority> getAuthorities();
    
        Object getCredentials();
    
        Object getDetails();
    
        Object getPrincipal();
    
        boolean isAuthenticated();
    
        void setAuthenticated(boolean var1) throws IllegalArgumentException;
    }
    

    由源码可知,Authentication(认证信息),主要包含了以下内容

    • getAuthorities => 可用于访问受保护资源时的权限验证

    • getCredentials => 初次认证的时候,进行填充,认证成功后将被清空

    • getDetails=> 暂不清楚,猜测应该是记录哪些保护资源已经验证授权,下次不用再验证,等等。

    • Pirncipal => 类似于 UserDetails(用户信息)

    • isAuthenticated => 是否已认证成功

    参考资源

    https://blog.csdn.net/baidu_38225647/article/details/104396392

    https://www.cnblogs.com/longfurcat/p/9417912.html

    https://blog.csdn.net/chihaihai/article/details/104830066

    每天学习一点点,每天进步一点点。

  • 相关阅读:
    JDBC JAVA数据库插入语句
    uri与url
    struts标签库
    jdbc使用
    mysql安装配置
    Json Web Token
    实现一个简单vue
    vue v2.5.0源码-双向数据绑定
    vue v2.5.0源码-初始化流程
    webpack
  • 原文地址:https://www.cnblogs.com/youcoding/p/14571010.html
Copyright © 2011-2022 走看看