Java Spring OAuth2+;JWT,如何将外部访问令牌映射到本地用户
我目前正在用Spring开发一个web服务。我想为用户提供通过外部OAuth服务登录的可能性,例如google、github,。。。以及传统的用户名/密码登录。Pojo wise,我有以下设置:Java Spring OAuth2+;JWT,如何将外部访问令牌映射到本地用户,java,spring-boot,spring-oauth2,Java,Spring Boot,Spring Oauth2,我目前正在用Spring开发一个web服务。我想为用户提供通过外部OAuth服务登录的可能性,例如google、github,。。。以及传统的用户名/密码登录。Pojo wise,我有以下设置: 每个用户都与身份验证方法有一对多的关系 每个AuthenticationMethod都有一个AuthenticationProvider(例如google,github,local),并存储此验证方法的子,以及相应的用户。对于本地身份验证,它是用户的ID 每个AuthenticationProvide
- 每个
都与用户
有一对多的关系身份验证方法
- 每个
都有一个AuthenticationMethod
(例如AuthenticationProvider
,google
,github
),并存储此验证方法的local
子
,以及相应的
用户
。对于本地身份验证,它是用户的ID
- 每个
的AuthenticationProvider==local
额外存储一个密码AuthenticationMethod
JWTAccessToken
,其中包含用户名(前端从未看到客户机机密
,因此在这种情况下可以接受密码
授权)
我还能够通过authorization\u request
grant过程从外部OAuth提供商(google、github等)检索访问令牌,该过程包含来自所述提供商的用户的sup
问题
我需要将外部子对象
映射到用户
对象。从理论上讲,两个不同的用户可能在两个不同的外部提供商处拥有相同的sub
,因此我还必须检查发行人,从而产生一个讨厌的if-else
结构。此外,从JWT令牌到用户
的转换必须在需要授权的每次访问中执行
解决方案的想法
我想做的是向外部生成的JWT添加信息。这显然是不可能的,因为我无法“重新签名”外部JWT。我的想法是截取外部JWT并发出一个包含用户名的本地JWT,从而仅将外部JWT用于初始身份验证
在春天是否有一种内在的可能性来实现我想要的?或者有解决这个问题的“最佳实践”吗?最佳实践是让OAuth2服务器向JWT添加用户名作为附加声明。Spring已经有了一个句柄,从JWT获取“user_name”声明并将其用作主要对象 问题是:我无法更改外部访问令牌,因此我无法添加额外的声明。我认为Spring没有任何内置功能来帮助您解决这个问题。您是否检查了OAuth2服务器上的JWT令牌?也许他们有额外的声明可以用来获取用户名。令牌不是问题所在。我可以找到对应于令牌的
用户
。问题是令牌拦截。我不希望前端看到外部标记。@Turing85为什么不?从外部提供程序获取令牌的用户被认证为令牌中详细信息的所有者。您必须让用户将数据传递给您。我认为您应该考虑将电子邮件声明始终附加到令牌。很抱歉,我不知道如何在Spring中实现这一点,但实际上,您希望验证用户的令牌(在ASP中,我们使用Owin middilewhere自动执行此操作),然后获取用户声明,该声明应该包含他们的电子邮件。任何用户都可以向您的服务器发送数据。JWT包含原始可读数据,以及相同数据的签名版本。为了确保这是合法的,您的后端需要使用谷歌的公钥来解码JWT的签名,并检查它是否与有效负载数据相同。用户无法向您发送伪造的JWT,因为他们无法对数据进行编码(谷歌必须这样做)。谷歌让它变得稍微困难一些,因为他们在访问代码中加入了另一个步骤(出于其他原因),但这个概念仍然存在: