欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SecurityContextHolder.getContext().getAuthentication().getPrincipal()获取到的是username而不是UserDetails

程序员文章站 2022-06-28 13:31:58
1.问题引入我在使用SpringSecurity+JWT做权限认证的时候, @PreAuthorize("@el.check(‘system:user:query’)")使用上面这个注解判断用户是否有拥有方法级的操作权限,但是在使用下方这个方法获取当前登陆用户时只获取到了用户名,而不是UserDetails对象。SecurityContextHolder.getContext().getAuthentication().getPrincipal()2.解决思路查看登陆成功后是否保存了 Authen...

1.问题引入

我在使用SpringSecurity+JWT做权限认证的时候, @PreAuthorize("@el.check(‘system:user:query’)")
使用上面这个注解判断用户是否有拥有方法级的操作权限,但是在使用下方这个方法获取当前登陆用户时只获取到了用户名,而不是UserDetails对象。
SecurityContextHolder.getContext().getAuthentication().getPrincipal()

2.解决思路

查看登陆成功后是否保存了 Authentication auth
虽然已删除打印,但是测试时是能打印auth的,其中包含UserDetails

    @Override
    protected void successfulAuthentication(HttpServletRequest req, HttpServletResponse res, FilterChain chain,
                                            Authentication auth) throws IOException, ServletException {
        SecurityUser user = (SecurityUser) auth.getPrincipal();
        String token = tokenManager.createToken(user.getCurrentUserInfo().getAccount());

        SecurityContextHolder.getContext().setAuthentication(auth);

        redisUtil.set(user.getCurrentUserInfo().getAccount(),user, GlobalConstant.REDIS_SAVE_TIME);
        log.info(" 3.登录成功保存用户达到redis并返回token=="+token);
        ResponseUtil.out(res, ResultJson.ok().data(GlobalConstant.ACCESS_TOKEN, token));
    }

而下方代码中.getAuthentication().getPrincipal()获取到的是username,导致认证出现问题

    /**
     * 获取当前登录的用户
     * @return UserDetails
     */
    public static UserDetails getCurrentUser() {
        final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null) {
            throw new BizException(CommonEnum.STATUS_EXPIRED);
        }
        if (authentication.getPrincipal() instanceof UserDetails) {
            UserDetails userDetails = (UserDetails) authentication.getPrincipal();
            UserDetailsService userDetailsService = SpringContextHolder.getBean(UserDetailsService.class);
            return userDetailsService.loadUserByUsername(userDetails.getUsername());
        }
        throw new BizException(CommonEnum.NOT_FIND_LOGIN_INFORMATION);
    }

后来才发现登陆授权是没有出问题的,但是当请求拿着token来鉴权的时候却出错了。因为我自己写的token判定过滤器,所以我反复检查代码终于发现问题: user.getUsername()

                    logger.info("4.更具token访问授权==" + user.getAuthorities());
                    return new UsernamePasswordAuthenticationToken(user.getUsername(), null, user.getAuthorities());

改成
UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
就正确了

本文地址:https://blog.csdn.net/weixin_42408648/article/details/110190327