• SecurityContext


    获取SecurityContext

    通过使用SecurityContextHolder就可以得到SecurityContext对象了,可以直接使用SecurityContext对象来获取当前的认证信息

    @RequestMapping("/index")

        public String index(){

            SecurityContext context = SecurityContextHolder.getContext();

            Authentication authentication = context.getAuthentication();

            User user = (User) authentication.getPrincipal();

            System.out.println(user.getUsername());

            System.out.println(user.getAuthorities());

            return "index";

        }

    通过SecurityContext我们就可以快速获取当前用户的名称和授权信息

    还可以直接从Session中获取SecurityContext

    @RequestMapping("/index")

    public String index(@SessionAttribute("SPRING_SECURITY_CONTEXT") SecurityContext context){

        Authentication authentication = context.getAuthentication();

        User user = (User) authentication.getPrincipal();

        System.out.println(user.getUsername());

        System.out.println(user.getAuthorities());

        return "index";

    }

    SecurityContext存储策略

    SecurityContextHolder是有一定的存储策略的,SecurityContextHolder中的SecurityContext对象会在一开始请求到来时被设定,至于存储方式其实是由存储策略决定的。如果创建一个子线程去获取是无法获取到认证信息的

    @RequestMapping("/index")

    public String index(){

        new Thread(() -> {   //创建一个子线程去获取

            SecurityContext context = SecurityContextHolder.getContext();

            Authentication authentication = context.getAuthentication();

            User user = (User) authentication.getPrincipal();   //NPE

            System.out.println(user.getUsername());

            System.out.println(user.getAuthorities());

        });

        return "index";

    }

    SecurityContextHolder的存储策略默认是`MODE_THREADLOCAL`,它是基于ThreadLocal实现的,`getContext()`方法本质上调用的是对应的存储策略实现的方法

    SecurityContextHolderStrategy有三个实现类

    * GlobalSecurityContextHolderStrategy:全局模式,不常用

    * ThreadLocalSecurityContextHolderStrategy:基于ThreadLocal实现,线程内可见

    * InheritableThreadLocalSecurityContextHolderStrategy:基于InheritableThreadLocal实现,线程和子线程可见

    如果需要在子线程中获取,那么需要修改SecurityContextHolder的存储策略,在初始化的时候设置

    1. @PostConstruct
    2. public void init(){
    3. SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
    4. }

    SecurityContext的生命周期

    SecurityContext的生命周期:请求到来时从Session中取出,放入SecurityContextHolder中,请求结束时从SecurityContextHolder取出,并放到Session中,实际上就是依靠Session来存储的,一旦会话过期验证信息也跟着消失。

  • 相关阅读:
    设计模式——组合模式
    Springboot毕设项目高校重点学科建设管理系统55290(java+VUE+Mybatis+Maven+Mysql)
    修改hosts 不生效? 三种方法解决
    Vuex获取、修改参数值及异步数据处理
    Java-多线程-设计模式
    期权里的资金变化
    使用Java和PostGis的全国A级风景区数据入库实战
    LeetCode 热题 100-49. 字母异位词分组
    js写一个判断字符串是否能够转为JSON 的函数
    安卓Java面试题21-30
  • 原文地址:https://blog.csdn.net/weixin_51992178/article/details/127577219