springSecurity系列之 SecurityContextHolder与SecurityContext

SecurityContextHolder

SecurityContextHolder 是spring security 的基础工具类。这是一个工具类,只提供一些静态方法。这个工具类的目的是用来保存应用程序中当前使用人的安全上下文。将给定SecurityContext与当前执行线程关联。

官网介绍英文官网
主要方法在这里插入图片描述

SecurityContextHolder.getContext()

获取安全上下文SecurityContext。

安全上下文 SecurityContext

SecurityContext 可以理解成一个 存储 Authentication 的容器。Authentication 是一个用户凭证接口用来作为用户认证的凭证使用,通常常用的实现有 认证用户 UsernamePasswordAuthenticationToken 和 匿名用户AnonymousAuthenticationToken。其中 UsernamePasswordAuthenticationToken 包含了 UserDetails , AnonymousAuthenticationToken 只包含了一个字符串 anonymousUser 作为匿名用户的标识。
比如我们接受前端发起来的请求,我们在自己定义spring security 过滤器链中对每个请求进行处理。
获取用户信息和对应权限并将其封装成UsernamePasswordAuthenticationToken

   private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
        // 前端将token放在header里,每次发送请求的时候携带。
        String token = request.getHeader("token");
        if (token != null && !"".equals(token.trim())) {
            String userName = tokenManager.getUserFromToken(token);
            // 获取用户名,在redis中得到相应的权限
            List<String> permissionValueList = (List<String>) redisTemplate.opsForValue().get(userName);
            Collection<GrantedAuthority> authorities = new ArrayList<>();
            for(String permissionValue : permissionValueList) {
                if(StringUtils.isEmpty(permissionValue)) continue;
                // 将每一个权限值放到SimpleGrantedAuthority
                SimpleGrantedAuthority authority = new SimpleGrantedAuthority(permissionValue);
                // 用于授权
                authorities.add(authority);
            }

            if (!StringUtils.isEmpty(userName)) {

                return new UsernamePasswordAuthenticationToken(userName, token, authorities);
            }
            return null;
        }
        return null;
    }

将UsernamePasswordAuthenticationToken 放入SecurityContext 中

  @Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        logger.info("================="+req.getRequestURI());
        //不是admin
        if(req.getRequestURI().indexOf("admin") == -1) {
            chain.doFilter(req, res);
            return;
        }

        UsernamePasswordAuthenticationToken authentication = null;
        try {
            //获取到封装好的数据
            authentication = getAuthentication(req);
        } catch (Exception e) {
            ResponseUtil.out(res, Result.error());
        }

        if (authentication != null) {
            //
            SecurityContextHolder.getContext().setAuthentication(authentication);
        } else {
            ResponseUtil.out(res, Result.error());
        }
        chain.doFilter(req, res);
    }

重点来了我们可以在接口中通过 SecurityContextHolder 获取相应的数据

    @GetMapping("info")
    public Result info(){
        //获取当前登录用户用户名
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        Map<String, Object> userInfo = indexService.getUserInfo(username);
        return Result.sucess().data(userInfo);
    }
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值