状态如何在 Spring OAuth2 中进行编码或加密?

Posted

技术标签:

【中文标题】状态如何在 Spring OAuth2 中进行编码或加密?【英文标题】:How does state get encoded or encrypted in Spring OAuth2? 【发布时间】:2016-09-19 15:27:13 【问题描述】:

state 参数与 Spring OAuth2 中的 _csrf 令牌相关的具体程度如何? state_csrf 的加密版本吗? p>

另外,在将新的_csrf 值封装到 Spring OAuth2 中的新 state 参数之前,应该使用什么特定的 Java 语法来编码和加密它?


**上下文:**

客户端应用程序将用户的网络浏览器从客户端应用程序重定向到授权服务器的身份验证服务器/登录页面。然后,在授权服务器应用程序中,OncePerRequestFilter 的自定义实现用于将到 /oauth/authorize?(list of params) 的请求重定向到额外的身份验证步骤,最终重定向回到 /oauth/authorize?(list of params) 的新请求。问题是 _csrf 令牌在附加身份验证步骤期间发生更改,以及 the documentation indicates that _csrf is used as the state parameter。这意味着授权服务器可能需要更新state 值以反映新的_csrf


**“状态”是如何生成的:**
问题在于,在客户端应用程序使用`OAuth2ClientAuthenticationProcessingFilter` 传输信息以供身份验证服务器在通过上述身份验证步骤对用户进行身份验证时使用之前,客户端应用程序已经设置了“状态”的编码和加密值。 一些研究表明,`state` 键是由客户端使用`DefaultStateKeyGenerator` 生成的,而客户端又使用`RandomValueStringGenrator` 生成6 个字符的状态值。

例如在对/oauth/authorize?(list of params)的原始请求中,原始的_csrf值被编码为fupS1L,如下url所示:

/oauth/authorize?client_id=acme&redirect_uri=http://localhost:8080/login&response_type=code&state=fupS1L

如果在重定向流程期间_csrf 值更改为a69fd23a-a393-4b27-a685-a323fd31db9a,则状态参数中fupS1L 的值将不再有效,并且生成的令牌将无权允许访问受保护的资源。

为了将新的_csrf 值转换为类似于fupS1L 的加密值,我应该使用什么特定的语法来传递给函数state 参数?

另外,state 变量和_csrf 令牌之间有什么关系吗? DefaultStateKeyGenerator 使用的 RandomValueStringGenerator 似乎只是创建了一个随机的 6 个字符的字符串。我希望深入研究代码甚至编写代码的人给出权威的答案。我正在对代码进行深入审查,因此阅读RandomValueStringGenerator 源代码并说状态与csrf 令牌无关的偶然路人不会增加任何价值。然而,API 的作者会告诉我们它是如何工作的,从而为我们提供了很多帮助。


**弹簧注意事项:**
它不应该需要这么多的挖掘来找到这样一个简单事物的文档。

【问题讨论】:

【参考方案1】:

我知道它已经很老了,因为它被问到了。仍然分享我现在所知道的,因为我已经通过类似的要求在“状态”参数中传递深度链接。在成功的 oauth 登录会话后,当流从 auth-server 返回时,我想重定向到此深层链接。

主要是我遵循了这个 SOF 答案 -> https://***.com/a/52462787/5107365。这建议扩展 DefaultStateKeyGenerator 以使用从请求到 AAS 的 deeplink 参数来加密+编码以设置为“状态”参数。并且,然后使用 OAuth2ClientAuthenticationProcessingFilter.AuthenticationSuccessHandler 的自定义实现来覆盖确定TargetUrl 方法,以在认证成功后流回来时对状态参数进行解码+解密。希望它能帮助有类似需求的人。

【讨论】:

以上是关于状态如何在 Spring OAuth2 中进行编码或加密?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spring Security 中动态指定 OAuth2 资源详细信息?

使用Spring启动进行Oauth2身份验证

无状态的 Spring Security oauth2 提供者

使用 OAuth2 和 JWT 的 Spring Security:编码密码看起来不像 BCrypt

如何在 Spring OAuth2 中仅通过 client_id 和 secret 进行授权?

如何在 Spring Boot 中实现 oAuth2 和 JWT 身份验证? [关闭]