Spring Security 实战干货:如何获取当前用户信息

举报
码农小胖哥 发表于 2022/04/01 00:19:39 2022/04/01
【摘要】 在某些场景中我们需要获取当前的用户是谁?如果你使用了Spring Secrity作为安全框架你可以通过以下手段获取当前用户。 SecurityContext 无论是有状态的Session模式还是流行的JWT模式你都可以通过SecurityContext来获取当前的用户: Authentication authe...

在某些场景中我们需要获取当前的用户是谁?如果你使用了Spring Secrity作为安全框架你可以通过以下手段获取当前用户。

SecurityContext

无论是有状态的Session模式还是流行的JWT模式你都可以通过SecurityContext来获取当前的用户:


   
  1. Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
  2. String currentPrincipalName = authentication.getName();

当然这种方式是不够严谨的,如果接口允许匿名访问很可能返回一个匿名用户,而匿名用户并不能直接通过getName获取,所以我们需要优化上面的逻辑为:


   
  1. Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
  2. if (!(authentication instanceof AnonymousAuthenticationToken)) {
  3.     String currentUserName = authentication.getName();
  4.     return currentUserName;
  5. }else{
  6.     throw RuntimeException("No User")
  7. }

其实我平常使用这种方式的最多,我喜欢使用一个抽象的父类控制器来封装获取当前用户的方法。

Principal

java.security.Principal对象也可以获取当前的用户信息,在Spring Security中该对象表现为Authentication对象,如果我们在Spring MVC接口中定义Principal对象也可以获取当前用户:


   
  1. @GetMapping("/currentusername")
  2. public String currentUserName(Principal principal) {
  3.         return principal.getName();
  4. }

同理Authentication对象也是可以的:


   
  1.  @GetMapping("/currentusername")
  2.  public String currentUserName(Authentication authentication) {
  3.         return authentication.getName();
  4.  }

AuthenticationPrincipal

很多时候我们自定义了用户对象UserDetails, 我们可以通过Spring Security 4.0提供的注解@AuthenticationPrincipal来获取当前用户的自定义UserDetails对象。如果CustomUserUserDetails的实现,那么我们可以:


   
  1. @GetMapping("/currentusername")
  2.  public String currentUserName(@AuthenticationPrincipal CustomUser customUser) {
  3.    return customUser.getUsername();
  4. }

更简单点的话:


   
  1. @GetMapping("/currentusername")
  2.  public String currentUserName(@AuthenticationPrincipal(expression = "username") String username) {
  3.    return username;
  4. }

这需要CustomUser包含一个getUsername方法。

甚至我们自定义一个注解也是可以的:


   
  1. @Target({ElementType.PARAMETER, ElementType.TYPE})
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. @AuthenticationPrincipal
  5. public @interface CurrentUser {}

CurrentSecurityContext

Spring Security 5 提供了一个新的注解@CurrentSecurityContext来获取当前用户的安全上下文,你可以:


   
  1. @GetMapping("/currentusername")
  2. public String currentUserName(@CurrentSecurityContext(expression = "authentication"
  3.   Authentication authentication) {
  4.         return authentication.getName();
  5. }

当然你还可以通过expression参数声明SpEL表达式来获取其它属性,例如获取Principal对象:


   
  1. @GetMapping("/principal")
  2. public String getPrincipal(@CurrentSecurityContext(expression = "authentication.principal"
  3.   Principal principal) { 
  4.     return principal.getName(); 
  5. }

HttpServletRequest

据说HttpServletRequestgetUserPrincipal()方法也可以,但是我没有用过,感兴趣的同学可以试试能不能在Spring Security框架中直接通过该方法获取。

总结

今天总结了如何在Spring Security获取当前用户的各种方法,它们的各自场景都略有不同,你可以根据这些罗列选择最适合你的应用场景。好了今天的分享就到这里,我是:码农小胖哥,多多关注,获取更多有用的编程干货。

线上SQL脚本执行错了出事之后互相甩锅怎么办?

2021-05-28

Spring MVC用ResponseEntity返回可实现更强大的功能

2021-05-26

文章来源: felord.blog.csdn.net,作者:码农小胖哥,版权归原作者所有,如需转载,请联系作者。

原文链接:felord.blog.csdn.net/article/details/117433383

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。