Spring Security 注解AuthenticationPrincipal 失效排查

  • Post author:
  • Post category:其他


#背景

项目使用了springframework.security

接口入参使用了springframework.security 注解 @AuthenticationPrincipal

 /**
     * 获得个人资料
     */
    @PostMapping(value = "/getUserPersonalInfo", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @PermissionCheck(value = "ROLE_USER")
    public String getUserPersonalInfo(@AuthenticationPrincipal Principal principal){
        String username = principal.getName();
        try {
            DataMap data = userService.getUserPersonalInfoByUsername(username);
            return JsonResult.build(data).toJSON();
        } catch (Exception e){
            log.error("[{}] get user personal info exception", username, e);
        }
        return JsonResult.fail(CodeType.SERVER_EXCEPTION).toJSON();
    }

注解失效,前端请求接口的时候发现

Principal 为空



问题排查

这个问题不复杂,

String username = principal.getName();

报NPE

spring security 框架未处理

principal.setName()

的逻辑,具体代码位置不分析了,

一般分布式项目很少使用 security 框架,基本上都是基于jwt + redis 实现分布式登录验证,验证的逻辑放在网关里。



怎么解决

排查了 注解 @AuthenticationPrincipal 使用方法

发现一篇文件介绍 spring security 怎么获取用户的登录信息

发现了新的主键:


@CurrentSecurityContext

用法:


    /**
     * 获得个人资料
     */
    @PostMapping(value = "/getUserPersonalInfo", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @PermissionCheck(value = "ROLE_USER")
    public String getUserPersonalInfo(@CurrentSecurityContext(expression = "authentication")  Authentication authentication){
        String username =authentication.getName();
        try {
            DataMap data = userService.getUserPersonalInfoByUsername(username);
            return JsonResult.build(data).toJSON();
        } catch (Exception e){
            log.error("[{}] get user personal info exception", username, e);
        }
        return JsonResult.fail(CodeType.SERVER_EXCEPTION).toJSON();
    }

这个是经过2这个小时的排查的结果

期间 使用了简单直接的方法获取用户信息

  Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        String loginName = auth.getName();

想着如果spring security 框架没有自己处理,是不是自己写一个拦截器处理,或者是不是需要自己实现spring security 中自定义拦截器

后边发现或许是项目中的 spring security 版本升级导致,查看了maven 中的版本已经升级到了5.0

参考资料:

参考资料一


参考资料二

转载于:https://www.fancv.com/article/1661265334