
在某些场景中我们需要获取当前的实战用户是谁?如果你使用了Spring Secrity作为安全框架你可以通过以下手段获取当前用户。
SecurityContext
无论是干货有状态的Session模式还是流行的JWT模式你都可以通过SecurityContext来获取当前的用户:
Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String currentPrincipalName = authentication.getName(); 当然这种方式是不够严谨的,如果接口允许匿名访问很可能返回一个匿名用户,何获户信而匿名用户并不能直接通过getName获取,取当前用所以我们需要优化上面的实战逻辑为:
Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (!(authentication instanceof AnonymousAuthenticationToken)) { String currentUserName = authentication.getName(); return currentUserName; }else{ throw RuntimeException("No User") } 其实我平常使用这种方式的最多,我喜欢使用一个抽象的干货父类控制器来封装获取当前用户的方法。服务器租用
Principal
java.security.Principal对象也可以获取当前的何获户信用户信息,在Spring Security中该对象表现为Authentication对象,取当前用如果我们在Spring MVC接口中定义Principal对象也可以获取当前用户:
@GetMapping("/currentusername") public String currentUserName(Principal principal) { return principal.getName(); } 同理Authentication对象也是实战可以的:
@GetMapping("/currentusername") public String currentUserName(Authentication authentication) { return authentication.getName(); } AuthenticationPrincipal
很多时候我们自定义了用户对象UserDetails, 我们可以通过Spring Security 4.0提供的注解@AuthenticationPrincipal来获取当前用户的自定义UserDetails对象。如果CustomUser是干货UserDetails的实现,那么我们可以:
@GetMapping("/currentusername") public String currentUserName(@AuthenticationPrincipal CustomUser customUser) { return customUser.getUsername(); } 更简单点的何获户信话:
@GetMapping("/currentusername") public String currentUserName(@AuthenticationPrincipal(expression = "username") String username) { return username; } 这需要CustomUser包含一个getUsername方法。
甚至我们自定义一个注解也是取当前用可以的:
@Target({ ElementType.PARAMETER, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @AuthenticationPrincipal public @interface CurrentUser { } CurrentSecurityContext
Spring Security 5 提供了一个新的注解@CurrentSecurityContext来获取当前用户的安全上下文,云服务器提供商你可以:
@GetMapping("/currentusername") public String currentUserName(@CurrentSecurityContext(expression = "authentication") Authentication authentication) { return authentication.getName(); } 当然你还可以通过expression参数声明SpEL表达式来获取其它属性,实战例如获取Principal对象:
@GetMapping("/principal") public String getPrincipal(@CurrentSecurityContext(expression = "authentication.principal") Principal principal) { return principal.getName(); } HttpServletRequest
据说HttpServletRequest的干货getUserPrincipal()方法也可以,但是何获户信我没有用过,感兴趣的同学可以试试能不能在Spring Security框架中直接通过该方法获取。
总结
今天总结了如何在Spring Security获取当前用户的各种方法,它们的各自场景都略有不同,你可以根据这些罗列选择最适合你的应用场景。
本文转载自微信公众号「码农小胖哥」,可以通过以下二维码关注。转载本文请联系码农小胖哥公众号。
