SpringSecurity中WebSecurity和HttpSecurity的关系-SpringSecurity获取当前用户信息-《Java笔记》

admin 2025-10-19 04:35:39 编程 来源:ZONE.CI 全球网 0 阅读模式

Java Spring Security在某些场景中需要获取当前的用户是谁?如果使用了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()方法也可以。

以太坊cppgolang区别 编程

以太坊cppgolang区别

以太坊是一种去中心化的开源平台,它采用智能合约技术,旨在构建和运行不受干扰的分布式应用程序。作为目前最受欢迎的区块链平台之一,以太坊提供了多种编程语言的支持,其
progolang 编程

progolang

Go语言(Golang)是由Google开发的一门静态类型编程语言。作为一名专业的Golang开发者,我深知这门语言的优势和特点。在本文中,我将介绍Golang
golangn个发送者 编程

golangn个发送者

Golang是一种开源的编程语言,由Google团队开发,旨在提高程序的并发性和简化软件开发过程。在Go语言中,有时需要向多个接收者发送信息。本文将介绍如何在G
golang技能图谱 编程

golang技能图谱

从互联网行业的快速发展到人工智能技术的日益成熟,各种编程语言也应运而生。而在这众多的编程语言中,Golang(即Go)作为一门强大且高效的开发语言备受关注。Go
评论:0   参与:  6