我目前正在使用Spring开发Web服务。我想为用户提供通过外部OAuth服务登录的可能性,例如: google,github,...以及传统的用户名/密码登录。 Pojo-wise,我有以下设置:
User
与AuthenticationMethod
s 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中是否有内置的可能性来实现我的目标?或者是否有“最佳实践”来解决这个问题?
答案 0 :(得分:0)
最佳做法是让OAuth2服务器添加用户名作为对JWT的附加声明。 Spring已经有一个句柄,它从JWT获取“user_name”声明并将其用作Principal对象。