在 spring 引导 RestController.. 中从 SecurityContextholder 获取用户 ID 是个好主意吗?

Is it good idea to take user id from SecurityContextholder in spring boot RestController..?

我正在为电子商务应用程序开发 spring boot rest 应用程序,假设我有端点 /shipping-address 它将为用户获取所有已保存的地址,从 SecurityContextHolder 中获取用户 ID 是个好主意,比如

Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    Long userId;
    if (principal instanceof UserPrincipal) {
        userId = ((UserPrincipal) principal).getId();
    }

或者我应该在请求正文中从客户端传递..?哪个是正确的..?如果我从 SecurityContextHolder 获取水平缩放时是否有问题..??

请帮忙,我是后端开发的新手。谢谢

从 SecurityContext 中获取 userId 是个好主意,因为它可以防止黑客入侵您的应用程序。

如果您从客户端传递 userId,有人可能会拦截请求并更改 userId。

关于缩放,这取决于您如何验证用户。如果它是基本的或基于令牌的并且不依赖于会话信息。一切都会好起来的。

安全上下文

在 Spring MVC 中使用 SecurityContext 没有问题。

你可以使用类似的东西:

@RestController
@RequestMapping(path = "/auth")
@Slf4j
public class AuthResource {

    @GetMapping(path = "whoami", produces = MediaType.APPLICATION_JSON_VALUE)
    @PreAuthorize("isAuthenticated()")
    public ResponseEntity<String> whoami(@AuthenticationPrincipal() UserDetails userDetails) {
        String login = userDetails.getUsername();
        return ResponseEntity.ok(login);
    }

}

来自 Spring 安全性的注释 @AuthenticationPrincipal 将简化您的代码。

会话存储

默认情况下,会话将由 HttpSession (cookie JSESSIONID) 支持。 因此,如果使用负载均衡器,您将需要诸如粘性会话之类的东西。

但是,会话可以存储在其他地方,例如关系数据库 (JDBC) 或 Redis:这就是 Spring Session 可以做的。

另见 Control the Session with Spring Security

您也可以选择不使用具有 Spring 安全性的会话:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}