Spring:为啥在端点中返回整个 OAuth2User 是不好的?

Posted

技术标签:

【中文标题】Spring:为啥在端点中返回整个 OAuth2User 是不好的?【英文标题】:Spring: Why is it bad to return a whole OAuth2User in an endpoint?Spring:为什么在端点中返回整个 OAuth2User 是不好的? 【发布时间】:2021-08-22 06:33:54 【问题描述】:

我正在使用 Spring Boot 构建一个经过 OAuth2 身份验证的应用程序,遵循本教程:https://spring.io/guides/tutorials/spring-boot-oauth2/

在某一时刻,端点 /user 会发回当前登录的用户。

指南警告说:

“在端点中返回整个 OAuth2User 不是一个好主意,因为它可能包含您不希望向浏览器客户端透露的信息。”

但它没有提供更多信息 - 我不应该向浏览器客户端透露什么类型的信息?

谢谢!

【问题讨论】:

它可以是任何敏感的东西。如果您的用户对象上有密码哈希,那么有人可能会拿走这些密码并尝试离线破解它们,或者您的用户对象中的信用卡号等。 【参考方案1】:

在 Spring Security 5.x 中,OAuth2User 是特定的 OAuth2AuthenticatedPrincipal(与 UserDetails 非常相似,但没有任何密码概念)。即使没有密码,暴露它也可能(而且经常会)泄露敏感信息、身份验证方案的实现细节等。如果你愿意,你可以暴露它,但指南中的警告建议应该小心,以免暴露任何被认为是敏感的东西,你应该在直接暴露之前考虑替代方案。

例如,您可以考虑创建一个 CustomUser 类,该类使用自定义 OAuth2UserService(文档的 advanced configuration 部分中的各种示例)从 OAuth2User 的声明中填充。您还可以采取各种步骤将 Spring Security 中的 oauth2 用户表示与应用程序中的用户表示分离(例如,通过使用 @AuthenticationPrincipal 来解决您自己的自定义用户或访问声明)。如果应用程序本身不需要自定义用户,您可以简单地将 OAuth2User 的声明映射到自定义端点中的响应,如指南中所示。

最后,您可以结合所有这些技术,让您的 /user 端点再次成为“单线”,如下所示:

@Target(ElementType.PARAMETER, ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@AuthenticationPrincipal(expression = "customUser")
public @interface CurrentUser 
@GetMapping("/user")
public CustomUser user(@CurrentUser CustomUser customUser) 
    return customUser;

【讨论】:

以上是关于Spring:为啥在端点中返回整个 OAuth2User 是不好的?的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 2 Actuator 端点在 GET 请求上返回 405

为啥 Spring Boot Actuator 返回 404 而不是 401?

为啥 spring-boot-starter-jdbc 会破坏我的 REST 端点?

如何在 Spring Boot 中收听流式 API?

为啥我的所有 Spring Boot 执行器端点都是公开可用的?

为啥 GraphQL 查询返回 null?