当前位置:   article > 正文

Spring Security 注解AuthenticationPrincipal 失效排查

authenticationprincipal

#背景
项目使用了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();
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

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

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();
    }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

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

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

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

想着如果spring security 框架没有自己处理,是不是自己写一个拦截器处理,或者是不是需要自己实现spring security 中自定义拦截器
后边发现或许是项目中的 spring security 版本升级导致,查看了maven 中的版本已经升级到了5.0

参考资料:参考资料一

参考资料二

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/481526
推荐阅读
相关标签
  

闽ICP备14008679号