如何找到Spring Boot中当前登录的用户?

DP_*_*DP_ 38 java spring-boot

这个Spring Boot应用程序中,有一个Web服务,它为登录用户返回一些数据:

@RequestMapping("/resource")
public Map<String, Object> home() {
    Map<String, Object> model = new HashMap<String, Object>();
    model.put("id", UUID.randomUUID().toString());
    model.put("content", "Hello World");
    return model;
}
Run Code Online (Sandbox Code Playgroud)

想象一下,该方法的返回值取决于当前登录的用户.

如何找出该方法中登录的用户?

Rom*_*ner 84

按要求:

内部使用Spring Security的 Spring Boot 提供了一个SecurityContextHolder类,它允许通过以下方式查找当前经过身份验证的用户:

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
Run Code Online (Sandbox Code Playgroud)

认证实例现在提供了以下方法:

  • 获取登录用户的用户名: getPrincipal()
  • 获取经过身份验证的用户的密码: getCredentials()
  • 获取经过身份验证的用户的已分配角色: getAuthorities()
  • 获取经过身份验证的用户的详细信息: getDetails()

  • 或者更简单,更少侵入,只需添加一个类型为`Principal`的方法参数,如果您只对用户感兴趣,或者如果您想要更多,则添加`Authentication`.使您无需使用`SecurityContextHolder`. (14认同)
  • 获取登录用户的用户名: getPrincipal() =&gt; getName() ? (2认同)

Nik*_*ilP 12

您也可以简单地使用HttpServletRequest获取用户原则,

使用HttpServletRequest请求,

String user=request.getUserPrincipal().getName();
Run Code Online (Sandbox Code Playgroud)


Nik*_*laB 11

从Spring Security 3.2开始,您可以UserDetails通过在控制器方法内添加参数来获得当前登录的用户(您的实现):

import org.springframework.security.web.bind.annotation.AuthenticationPrincipal;

@RequestMapping("/resource")
public Map<String, Object> home(@AuthenticationPrincipal User user) {
   ..
}
Run Code Online (Sandbox Code Playgroud)

替换User为实现UserDetails接口的类的名称。

编辑:

由于Spring Security 4.0批注已移至其他软件包:

import org.springframework.security.core.annotation.AuthenticationPrincipal;
Run Code Online (Sandbox Code Playgroud)

  • @DanielMethner 这不应该发生,我在 Webflux 和非 Webflux 环境中的控制器中使用它,并且它在任何地方都有效。您可以提出一个新问题并发布您的配置、弹簧版本和控制器(它不起作用),我会看一下吗? (2认同)

ttu*_*lka 7

从 5.2 版开始,您可以使用CurrentSecurityContext注释:

@GetMapping("/hello")
public String hello(@CurrentSecurityContext(expression="authentication?.name")
                    String username) {
    return "Hello, " + username + "!";
}
Run Code Online (Sandbox Code Playgroud)


Dev*_*avo 6

一种方法是将java.security.Principal添加为参数,如下所示:

@RequestMapping("/resource")
public Map<String, Object> home(Principal principal) {
    Map<String, Object> model = new HashMap<String, Object>();
    model.put("id", UUID.randomUUID().toString());
    model.put("content", "Hello " + principal.getName());
    return model;
}
Run Code Online (Sandbox Code Playgroud)