Spring 安全,OAUTH2,动态客户端密码

Spring Security, OAUTH2, dynamic client-secret

Spring 安全版本 5.4.0

通常 client-id 和 client-secret 是由 Oauth2 提供商提供的值,它们对每个客户端都是永久性的,可以在配置文件中这样指定

spring:
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: google-client-id
            client-secret: google-client-secret

但在我的例子中,我有固定的 client-id,但 client-secret 是在每次尝试获取身份验证代码时根据某些参数生成的。 在最后的 class ClientRegistration 中,client-secret 被定义为一个字符串值,所以在我的例子中不可能采用这个 class

我的问题是在这种情况下是否可以使用 Spring 安全性,如果可以,那么 adopted/configured 是什么?

听起来你可能在做 PKCE

在这种情况下,you can leave the secret empty 和 Spring 安全部门将生成代码质询和验证程序作为 /authorize 请求的一部分。

来自文档:

Public Clients are supported using Proof Key for Code Exchange (PKCE). If the client is running in an untrusted environment (eg. native application or web browser-based application) and therefore incapable of maintaining the confidentiality of its credentials, PKCE will automatically be used when the following conditions are true:

client-secret is omitted (or empty)

client-authentication-method is set to "none" (ClientAuthenticationMethod.NONE)

如果您正在做一些自定义的事情,那么您可以考虑标准化为 PKCE。

但是,如果您不能这样做,那么 Spring 安全性会为 adding custom parameters to the /authorize and /token requests 提供各种挂钩。我建议看看 DefaultOAuth2AuthorizationRequestResolver#setAuthorizationRequestCustomizerDefaultAuthorizationCodeTokenResponseClient#setRequestEntityConverter.

您可以像这样在 DSL 中注册您的自定义授权请求和令牌请求:

http
    .oauth2Login((oauth2) -> oauth2
        .authorizeEndpoint((authorize) -> authorize
            .authorizeRequestResolver(...)
        )
        .tokenEndpoint((token) -> token
            .accessTokenResponseClient(...)
        )
    );