【发布时间】:2018-03-13 19:30:48
【问题描述】:
我目前正在使用 Spring 开发 Web 服务。我想为用户提供通过外部 OAuth 服务登录的可能性,例如谷歌,Github,...以及传统的用户名/密码登录。 POJO 方面,我有以下设置:
- 每个
User都与AuthenticationMethods 存在一对多关系 - 每个
AuthenticationMethod都有一个AuthenticationProvider(例如google、github、local),并存储了这个认证方法的sub和对应的User。如果是本地身份验证,则为用户 ID。 - 每个
AuthenticationMethod和AuthenticationProvider == local额外存储一个密码。
已经有效的方法
本地身份验证(用户名/密码)是通过自己的 OAuth2 身份验证服务器(Spring 应用程序的一部分)完成的,并返回一个包含用户名的 JWTAccessToken (前端永远不会看到 client_secret,因此是 password在这种情况下,赠款是可以接受的)。
我还能够通过authorization_request 授权过程从外部 OAuth 提供者(Google、Github 等)检索访问令牌,其中包含来自所述提供者的用户sup。
问题
我需要将外部sub 映射到User 对象。因为理论上,两个不同的用户可能在两个不同的外部提供商处拥有相同的sub,所以我还必须检查发行者,从而导致讨厌的if-else 构造。此外,每次需要授权的访问都必须执行从 JWT 令牌到 User 的转换。
解决方案的想法
我想做的是向外部生成的 JWT 添加信息。这显然是不可能的,因为我无法“重新签署”外部 JWT。我的想法是拦截外部 JWT 并发出包含用户名的本地 JWT,因此仅将外部 JWT 用于初始身份验证。
Spring 中是否有内置的可能性来完成我想要的?还是有解决这个问题的“最佳实践”?
【问题讨论】:
标签: java spring-boot spring-oauth2