|
此版本仍在开发中,尚未被视为稳定版本。如需最新稳定版本,请使用 Spring Security 7.0.4! |
协议端点
OAuth2 授权端点
OAuth2AuthorizationEndpointConfigurer 提供了自定义 OAuth2 授权端点 的能力。
它定义了扩展点,允许你自定义 OAuth2 授权请求 的预处理、主处理和后处理逻辑。
OAuth2AuthorizationEndpointConfigurer 提供以下配置选项:
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
http
.oauth2AuthorizationServer((authorizationServer) ->
authorizationServer
.authorizationEndpoint(authorizationEndpoint ->
authorizationEndpoint
.authorizationRequestConverter(authorizationRequestConverter) (1)
.authorizationRequestConverters(authorizationRequestConvertersConsumer) (2)
.authenticationProvider(authenticationProvider) (3)
.authenticationProviders(authenticationProvidersConsumer) (4)
.authorizationResponseHandler(authorizationResponseHandler) (5)
.errorResponseHandler(errorResponseHandler) (6)
.consentPage("/oauth2/v1/authorize") (7)
)
);
return http.build();
}
| 1 | authorizationRequestConverter():添加一个 AuthenticationConverter(预处理器),用于在尝试从 https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.1 中提取 OAuth2 授权请求(或同意)并转换为 OAuth2AuthorizationCodeRequestAuthenticationToken 或 OAuth2AuthorizationConsentAuthenticationToken 实例时使用。 |
| 2 | authorizationRequestConverters():设置一个 Consumer,用于访问默认的(以及可选添加的)List 列表,从而允许添加、删除或自定义特定的 AuthenticationConverter。 |
| 3 | authenticationProvider():添加一个用于对 AuthenticationProvider 或 OAuth2AuthorizationCodeRequestAuthenticationToken 进行身份验证的 OAuth2AuthorizationConsentAuthenticationToken(主处理器)。 |
| 4 | authenticationProviders():设置一个 Consumer,用于访问默认的(以及可选添加的)List 列表,从而允许添加、删除或自定义特定的 AuthenticationProvider。 |
| 5 | authorizationResponseHandler():用于处理已“认证”的 AuthenticationSuccessHandler 并返回 OAuth2AuthorizationResponse 的 https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2(后处理器)。 |
| 6 | errorResponseHandler():用于处理 AuthenticationFailureHandler 并返回OAuth2Error 响应 的 https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1(后处理器)。 |
| 7 | consentPage():在授权请求流程中,如果需要用户同意,则用于重定向资源所有者到自定义同意页面的URI。 |
OAuth2AuthorizationEndpointConfigurer 用于配置 OAuth2AuthorizationEndpointFilter,并将其注册到 OAuth2 授权服务器的 SecurityFilterChain @Bean 中。
OAuth2AuthorizationEndpointFilter 是处理 OAuth2 授权请求(及用户同意)的 Filter。
OAuth2AuthorizationEndpointFilter 的默认配置如下:
-
AuthenticationConverter— 一个由DelegatingAuthenticationConverter和OAuth2AuthorizationCodeRequestAuthenticationConverter组成的OAuth2AuthorizationConsentAuthenticationConverter。 -
AuthenticationManager— 一个由AuthenticationManager和OAuth2AuthorizationCodeRequestAuthenticationProvider组成的OAuth2AuthorizationConsentAuthenticationProvider。 -
AuthenticationSuccessHandler— 一个内部实现,用于处理“已认证”的OAuth2AuthorizationCodeRequestAuthenticationToken并返回OAuth2AuthorizationResponse。 -
AuthenticationFailureHandler— 一个内部实现,使用与OAuth2Error关联的OAuth2AuthorizationCodeRequestAuthenticationException,并返回该OAuth2Error响应。
自定义授权请求验证
OAuth2AuthorizationCodeRequestAuthenticationValidator 是用于验证授权码许可(Authorization Code Grant)中特定 OAuth2 授权请求参数的默认验证器。
默认实现会验证 redirect_uri 和 scope 参数。
如果验证失败,将抛出 OAuth2AuthorizationCodeRequestAuthenticationException 异常。
OAuth2AuthorizationCodeRequestAuthenticationProvider 提供了通过向 Consumer<OAuth2AuthorizationCodeRequestAuthenticationContext> 方法传入一个类型为 setAuthenticationValidator() 的自定义身份验证验证器,来覆盖默认授权请求验证的能力。
OAuth2AuthorizationCodeRequestAuthenticationContext 持有 OAuth2AuthorizationCodeRequestAuthenticationToken,其中包含 OAuth2 授权请求参数。 |
如果验证失败,身份验证验证器必须抛出OAuth2AuthorizationCodeRequestAuthenticationException。 |
在开发生命周期阶段,一个常见的用例是允许在 localhost 参数中使用 redirect_uri。
以下示例展示了如何配置 OAuth2AuthorizationCodeRequestAuthenticationProvider,并使用一个自定义的身份验证验证器,该验证器允许在 localhost 参数中使用 redirect_uri:
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
http
.oauth2AuthorizationServer((authorizationServer) ->
authorizationServer
.authorizationEndpoint(authorizationEndpoint ->
authorizationEndpoint
.authenticationProviders(configureAuthenticationValidator())
)
);
return http.build();
}
private Consumer<List<AuthenticationProvider>> configureAuthenticationValidator() {
return (authenticationProviders) ->
authenticationProviders.forEach((authenticationProvider) -> {
if (authenticationProvider instanceof OAuth2AuthorizationCodeRequestAuthenticationProvider) {
Consumer<OAuth2AuthorizationCodeRequestAuthenticationContext> authenticationValidator =
// Override default redirect_uri validator
new CustomRedirectUriValidator()
// Reuse default scope validator
.andThen(OAuth2AuthorizationCodeRequestAuthenticationValidator.DEFAULT_SCOPE_VALIDATOR);
((OAuth2AuthorizationCodeRequestAuthenticationProvider) authenticationProvider)
.setAuthenticationValidator(authenticationValidator);
}
});
}
static class CustomRedirectUriValidator implements Consumer<OAuth2AuthorizationCodeRequestAuthenticationContext> {
@Override
public void accept(OAuth2AuthorizationCodeRequestAuthenticationContext authenticationContext) {
OAuth2AuthorizationCodeRequestAuthenticationToken authorizationCodeRequestAuthentication =
authenticationContext.getAuthentication();
RegisteredClient registeredClient = authenticationContext.getRegisteredClient();
String requestedRedirectUri = authorizationCodeRequestAuthentication.getRedirectUri();
// Use exact string matching when comparing client redirect URIs against pre-registered URIs
if (!registeredClient.getRedirectUris().contains(requestedRedirectUri)) {
OAuth2Error error = new OAuth2Error(OAuth2ErrorCodes.INVALID_REQUEST);
throw new OAuth2AuthorizationCodeRequestAuthenticationException(error, null);
}
}
}
OAuth2 推送授权请求端点
OAuth2PushedAuthorizationRequestEndpointConfigurer 提供了自定义 OAuth2 推送授权请求端点 的能力。
它定义了扩展点,允许您自定义 OAuth2 推送授权请求 的预处理、主处理和后处理逻辑。
OAuth2PushedAuthorizationRequestEndpointConfigurer 提供以下配置选项:
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
http
.oauth2AuthorizationServer((authorizationServer) ->
authorizationServer
.pushedAuthorizationRequestEndpoint(pushedAuthorizationRequestEndpoint ->
pushedAuthorizationRequestEndpoint
.pushedAuthorizationRequestConverter(pushedAuthorizationRequestConverter) (1)
.pushedAuthorizationRequestConverters(pushedAuthorizationRequestConvertersConsumer) (2)
.authenticationProvider(authenticationProvider) (3)
.authenticationProviders(authenticationProvidersConsumer) (4)
.pushedAuthorizationResponseHandler(pushedAuthorizationResponseHandler) (5)
.errorResponseHandler(errorResponseHandler) (6)
)
);
return http.build();
}
| 1 | pushedAuthorizationRequestConverter():添加一个 AuthenticationConverter(预处理器),用于在尝试从 https://datatracker.ietf.org/doc/html/rfc9126#section-2.1 中提取 OAuth2 推送授权请求 并转换为 OAuth2PushedAuthorizationRequestAuthenticationToken 实例时使用。 |
| 2 | pushedAuthorizationRequestConverters():设置一个 Consumer,用于访问默认的(以及可选添加的)List 列表,从而允许添加、删除或自定义特定的 AuthenticationConverter。 |
| 3 | authenticationProvider():添加一个用于对 AuthenticationProvider 进行身份验证的 OAuth2PushedAuthorizationRequestAuthenticationToken(主处理器)。 |
| 4 | authenticationProviders():设置一个 Consumer,用于访问默认的(以及可选添加的)List 列表,从而允许添加、删除或自定义特定的 AuthenticationProvider。 |
| 5 | pushedAuthorizationResponseHandler():用于处理“已认证”的 AuthenticationSuccessHandler 并返回OAuth2 推送授权响应 的 https://datatracker.ietf.org/doc/html/rfc9126#section-2.2(后处理器)。 |
| 6 | errorResponseHandler():用于处理 AuthenticationFailureHandler 并返回OAuth2Error 响应 的 https://datatracker.ietf.org/doc/html/rfc9126#section-2.3(后处理器)。 |
OAuth2PushedAuthorizationRequestEndpointConfigurer 用于配置 OAuth2PushedAuthorizationRequestEndpointFilter,并将其注册到 OAuth2 授权服务器的 SecurityFilterChain @Bean 中。
OAuth2PushedAuthorizationRequestEndpointFilter 是处理 OAuth2 推送授权请求的 Filter。
OAuth2PushedAuthorizationRequestEndpointFilter 的默认配置如下:
-
AuthenticationConverter— 一个由DelegatingAuthenticationConverter组成的OAuth2AuthorizationCodeRequestAuthenticationConverter。 -
AuthenticationManager— 一个由AuthenticationManager组成的OAuth2PushedAuthorizationRequestAuthenticationProvider。 -
AuthenticationSuccessHandler— 一个内部实现,用于处理已“认证”的OAuth2PushedAuthorizationRequestAuthenticationToken并返回 OAuth2 推送授权响应。 -
AuthenticationFailureHandler— AnOAuth2ErrorAuthenticationFailureHandler.
自定义推送授权请求验证
OAuth2AuthorizationCodeRequestAuthenticationValidator 是用于验证授权码许可(Authorization Code Grant)中特定的 OAuth2 推送授权请求参数的默认验证器。
默认实现会验证 redirect_uri 和 scope 参数。
如果验证失败,将抛出一个 OAuth2AuthorizationCodeRequestAuthenticationException 异常。
OAuth2PushedAuthorizationRequestAuthenticationProvider 提供了通过向 Consumer<OAuth2AuthorizationCodeRequestAuthenticationContext> 方法传入一个类型为 setAuthenticationValidator() 的自定义身份验证验证器,来覆盖默认的推送授权请求验证的能力。
OAuth2AuthorizationCodeRequestAuthenticationContext 持有 OAuth2AuthorizationCodeRequestAuthenticationToken,其中包含 OAuth2 推送授权请求参数。 |
如果验证失败,身份验证验证器必须抛出OAuth2AuthorizationCodeRequestAuthenticationException。 |
在开发生命周期阶段,一个常见的用例是允许在 localhost 参数中使用 redirect_uri。
以下示例展示了如何配置 OAuth2PushedAuthorizationRequestAuthenticationProvider,并使用一个自定义的身份验证验证器,该验证器允许在 localhost 参数中使用 redirect_uri:
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
http
.oauth2AuthorizationServer((authorizationServer) ->
authorizationServer
.pushedAuthorizationRequestEndpoint(pushedAuthorizationRequestEndpoint ->
pushedAuthorizationRequestEndpoint
.authenticationProviders(configureAuthenticationValidator())
)
);
return http.build();
}
private Consumer<List<AuthenticationProvider>> configureAuthenticationValidator() {
return (authenticationProviders) ->
authenticationProviders.forEach((authenticationProvider) -> {
if (authenticationProvider instanceof OAuth2PushedAuthorizationRequestAuthenticationProvider) {
Consumer<OAuth2AuthorizationCodeRequestAuthenticationContext> authenticationValidator =
// Override default redirect_uri validator
new CustomRedirectUriValidator()
// Reuse default scope validator
.andThen(OAuth2AuthorizationCodeRequestAuthenticationValidator.DEFAULT_SCOPE_VALIDATOR);
((OAuth2PushedAuthorizationRequestAuthenticationProvider) authenticationProvider)
.setAuthenticationValidator(authenticationValidator);
}
});
}
static class CustomRedirectUriValidator implements Consumer<OAuth2AuthorizationCodeRequestAuthenticationContext> {
@Override
public void accept(OAuth2AuthorizationCodeRequestAuthenticationContext authenticationContext) {
OAuth2AuthorizationCodeRequestAuthenticationToken authorizationCodeRequestAuthentication =
authenticationContext.getAuthentication();
RegisteredClient registeredClient = authenticationContext.getRegisteredClient();
String requestedRedirectUri = authorizationCodeRequestAuthentication.getRedirectUri();
// Use exact string matching when comparing client redirect URIs against pre-registered URIs
if (!registeredClient.getRedirectUris().contains(requestedRedirectUri)) {
OAuth2Error error = new OAuth2Error(OAuth2ErrorCodes.INVALID_REQUEST);
throw new OAuth2AuthorizationCodeRequestAuthenticationException(error, null);
}
}
}
OAuth2 设备授权端点
OAuth2DeviceAuthorizationEndpointConfigurer 提供了自定义 OAuth2 设备授权端点 的能力。
它定义了扩展点,允许你自定义 OAuth2 设备授权请求的预处理、主处理和后处理逻辑。
OAuth2DeviceAuthorizationEndpointConfigurer 提供以下配置选项:
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
http
.oauth2AuthorizationServer((authorizationServer) ->
authorizationServer
.deviceAuthorizationEndpoint(deviceAuthorizationEndpoint ->
deviceAuthorizationEndpoint
.deviceAuthorizationRequestConverter(deviceAuthorizationRequestConverter) (1)
.deviceAuthorizationRequestConverters(deviceAuthorizationRequestConvertersConsumer) (2)
.authenticationProvider(authenticationProvider) (3)
.authenticationProviders(authenticationProvidersConsumer) (4)
.deviceAuthorizationResponseHandler(deviceAuthorizationResponseHandler) (5)
.errorResponseHandler(errorResponseHandler) (6)
.verificationUri("/oauth2/v1/device_verification") (7)
)
);
return http.build();
}
| 1 | deviceAuthorizationRequestConverter():添加一个 AuthenticationConverter(预处理器),用于在尝试从 https://datatracker.ietf.org/doc/html/rfc8628#section-3.1 中提取 OAuth2 设备授权请求 并转换为 OAuth2DeviceAuthorizationRequestAuthenticationToken 实例时使用。 |
| 2 | deviceAuthorizationRequestConverters():设置一个 Consumer,用于访问默认的(以及可选添加的)List 列表,从而允许添加、删除或自定义特定的 AuthenticationConverter。 |
| 3 | authenticationProvider():添加一个用于对 AuthenticationProvider 进行身份验证的 OAuth2DeviceAuthorizationRequestAuthenticationToken(主处理器)。 |
| 4 | authenticationProviders():设置一个 Consumer,用于访问默认的(以及可选添加的)List 列表,从而允许添加、删除或自定义特定的 AuthenticationProvider。 |
| 5 | deviceAuthorizationResponseHandler():用于处理已“认证”的 AuthenticationSuccessHandler 并返回 OAuth2DeviceAuthorizationResponse 的 https://datatracker.ietf.org/doc/html/rfc8628#section-3.2(后处理器)。 |
| 6 | errorResponseHandler():用于处理 AuthenticationFailureHandler 并返回OAuth2Error 响应 的 https://datatracker.ietf.org/doc/html/rfc6749#section-5.2(后处理器)。 |
| 7 | verificationUri():用于将资源所有者引导至辅助设备上的自定义终端用户验证页面的URI。 |
| OAuth2 设备授权端点默认处于禁用状态。 |
OAuth2DeviceAuthorizationEndpointConfigurer 用于配置 OAuth2DeviceAuthorizationEndpointFilter,并将其注册到 OAuth2 授权服务器的 SecurityFilterChain @Bean 中。
OAuth2DeviceAuthorizationEndpointFilter 是处理 OAuth2 设备授权请求的 Filter。
OAuth2DeviceAuthorizationEndpointFilter 的默认配置如下:
-
AuthenticationConverter— AnOAuth2DeviceAuthorizationRequestAuthenticationConverter. -
AuthenticationManager— 一个由AuthenticationManager组成的OAuth2DeviceAuthorizationRequestAuthenticationProvider。 -
AuthenticationSuccessHandler— 一个内部实现,用于处理“已认证”的OAuth2DeviceAuthorizationRequestAuthenticationToken并返回OAuth2DeviceAuthorizationResponse。 -
AuthenticationFailureHandler— AnOAuth2ErrorAuthenticationFailureHandler.
OAuth2 设备验证端点
OAuth2DeviceVerificationEndpointConfigurer 提供了自定义OAuth2 设备验证端点(或称“用户交互”)的功能。
它定义了扩展点,允许你自定义 OAuth2 设备验证请求的预处理、主处理和后处理逻辑。
OAuth2DeviceVerificationEndpointConfigurer 提供以下配置选项:
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
http
.oauth2AuthorizationServer((authorizationServer) ->
authorizationServer
.deviceVerificationEndpoint(deviceVerificationEndpoint ->
deviceVerificationEndpoint
.deviceVerificationRequestConverter(deviceVerificationRequestConverter) (1)
.deviceVerificationRequestConverters(deviceVerificationRequestConvertersConsumer) (2)
.authenticationProvider(authenticationProvider) (3)
.authenticationProviders(authenticationProvidersConsumer) (4)
.deviceVerificationResponseHandler(deviceVerificationResponseHandler) (5)
.errorResponseHandler(errorResponseHandler) (6)
.consentPage("/oauth2/v1/consent") (7)
)
);
return http.build();
}
| 1 | deviceVerificationRequestConverter():添加一个 AuthenticationConverter(预处理器),用于在尝试从 https://datatracker.ietf.org/doc/html/rfc8628#section-3.3 中提取OAuth2 设备验证请求(或同意)时,将其转换为 OAuth2DeviceVerificationAuthenticationToken 或 OAuth2DeviceAuthorizationConsentAuthenticationToken 的实例。 |
| 2 | deviceVerificationRequestConverters():设置一个 Consumer,用于访问默认的(以及可选添加的)List 列表,从而允许添加、删除或自定义特定的 AuthenticationConverter。 |
| 3 | authenticationProvider():添加一个用于对 AuthenticationProvider 或 OAuth2DeviceVerificationAuthenticationToken 进行身份验证的 OAuth2DeviceAuthorizationConsentAuthenticationToken(主处理器)。 |
| 4 | authenticationProviders():设置一个 Consumer,用于访问默认的(以及可选添加的)List 列表,从而允许添加、删除或自定义特定的 AuthenticationProvider。 |
| 5 | deviceVerificationResponseHandler():用于处理已“认证”的 AuthenticationSuccessHandler 并引导资源所有者返回其设备的 OAuth2DeviceVerificationAuthenticationToken(后处理器)。 |
| 6 | errorResponseHandler():用于处理 AuthenticationFailureHandler 并返回错误响应的 OAuth2AuthenticationException(后处理器)。 |
| 7 | consentPage():在设备验证请求流程中,如果需要用户授权同意,则用于将资源所有者重定向到的自定义同意页面的 URI。 |
| OAuth2 设备验证端点默认处于禁用状态。 |
OAuth2DeviceVerificationEndpointConfigurer 用于配置 OAuth2DeviceVerificationEndpointFilter,并将其注册到 OAuth2 授权服务器的 SecurityFilterChain @Bean 中。
OAuth2DeviceVerificationEndpointFilter 是处理 OAuth2 设备验证请求(及用户同意)的 Filter。
OAuth2DeviceVerificationEndpointFilter 的默认配置如下:
-
AuthenticationConverter— 一个由DelegatingAuthenticationConverter和OAuth2DeviceVerificationAuthenticationConverter组成的OAuth2DeviceAuthorizationConsentAuthenticationConverter。 -
AuthenticationManager— 一个由AuthenticationManager和OAuth2DeviceVerificationAuthenticationProvider组成的OAuth2DeviceAuthorizationConsentAuthenticationProvider。 -
AuthenticationSuccessHandler— 一个SimpleUrlAuthenticationSuccessHandler,用于处理已“认证”的OAuth2DeviceVerificationAuthenticationToken,并将用户重定向到成功页面(/?success)。 -
AuthenticationFailureHandler— 一个内部实现,使用与OAuth2Error关联的OAuth2AuthenticationException,并返回该OAuth2Error响应。
OAuth2 Tokens端点
OAuth2TokenEndpointConfigurer 提供了自定义 OAuth2 Tokens端点 的能力。
它定义了扩展点,允许你自定义 OAuth2 访问Tokens请求 的预处理、主处理和后处理逻辑。
OAuth2TokenEndpointConfigurer 提供以下配置选项:
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
http
.oauth2AuthorizationServer((authorizationServer) ->
authorizationServer
.tokenEndpoint(tokenEndpoint ->
tokenEndpoint
.accessTokenRequestConverter(accessTokenRequestConverter) (1)
.accessTokenRequestConverters(accessTokenRequestConvertersConsumer) (2)
.authenticationProvider(authenticationProvider) (3)
.authenticationProviders(authenticationProvidersConsumer) (4)
.accessTokenResponseHandler(accessTokenResponseHandler) (5)
.errorResponseHandler(errorResponseHandler) (6)
)
);
return http.build();
}
| 1 | accessTokenRequestConverter():添加一个 AuthenticationConverter(预处理器),用于在尝试从 https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.3 中提取 OAuth2 访问Tokens请求 并转换为 OAuth2AuthorizationGrantAuthenticationToken 实例时使用。 |
| 2 | accessTokenRequestConverters():设置一个 Consumer,用于访问默认的(以及可选添加的)List 列表,从而允许添加、删除或自定义特定的 AuthenticationConverter。 |
| 3 | authenticationProvider():添加一个用于对 AuthenticationProvider 进行身份验证的 OAuth2AuthorizationGrantAuthenticationToken(主处理器)。 |
| 4 | authenticationProviders():设置一个 Consumer,用于访问默认的(以及可选添加的)List 列表,从而允许添加、删除或自定义特定的 AuthenticationProvider。 |
| 5 | accessTokenResponseHandler(): 用于处理 OAuth2AccessTokenAuthenticationToken 并返回 OAuth2AccessTokenResponse 的 AuthenticationSuccessHandler(后置处理器)。 |
| 6 | errorResponseHandler():用于处理 AuthenticationFailureHandler 并返回OAuth2Error 响应 的 https://datatracker.ietf.org/doc/html/rfc6749#section-5.2(后处理器)。 |
OAuth2TokenEndpointConfigurer 用于配置 OAuth2TokenEndpointFilter,并将其注册到 OAuth2 授权服务器的 SecurityFilterChain @Bean 中。
OAuth2TokenEndpointFilter 是处理 OAuth2 访问Tokens请求的 Filter。
支持的授权许可类型包括 authorization_code、refresh_token、client_credentials、urn:ietf:params:oauth:grant-type:device_code 和 urn:ietf:params:oauth:grant-type:token-exchange。
OAuth2TokenEndpointFilter 的默认配置如下:
-
AuthenticationConverter— 一个由DelegatingAuthenticationConverter、OAuth2AuthorizationCodeAuthenticationConverter、OAuth2RefreshTokenAuthenticationConverter、OAuth2ClientCredentialsAuthenticationConverter和OAuth2DeviceCodeAuthenticationConverter组成的OAuth2TokenExchangeAuthenticationConverter。 -
AuthenticationManager— 一个由AuthenticationManager、OAuth2AuthorizationCodeAuthenticationProvider、OAuth2RefreshTokenAuthenticationProvider、OAuth2ClientCredentialsAuthenticationProvider和OAuth2DeviceCodeAuthenticationProvider组成的OAuth2TokenExchangeAuthenticationProvider。 -
AuthenticationSuccessHandler— AnOAuth2AccessTokenResponseAuthenticationSuccessHandler. -
AuthenticationFailureHandler— AnOAuth2ErrorAuthenticationFailureHandler.
自定义客户端凭证授权请求验证
OAuth2ClientCredentialsAuthenticationValidator 是用于验证特定 OAuth2 客户端凭证授权请求参数的默认验证器。
默认实现会验证 scope 参数。
如果验证失败,将抛出一个 OAuth2AuthenticationException 异常。
OAuth2ClientCredentialsAuthenticationProvider 提供了通过向 Consumer<OAuth2ClientCredentialsAuthenticationContext> 方法传入一个类型为 setAuthenticationValidator() 的自定义身份验证验证器,来覆盖默认请求验证的能力。
OAuth2ClientCredentialsAuthenticationContext 持有 OAuth2ClientCredentialsAuthenticationToken,其中包含 OAuth2 客户端凭证授权(Client Credentials Grant)请求参数。 |
如果验证失败,身份验证验证器必须抛出OAuth2AuthenticationException。 |
以下示例展示了如何配置 OAuth2ClientCredentialsAuthenticationProvider,并使用一个自定义的身份验证验证器来覆盖默认的 scope 验证:
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
http
.oauth2AuthorizationServer((authorizationServer) ->
authorizationServer
.tokenEndpoint(tokenEndpoint ->
tokenEndpoint
.authenticationProviders(configureAuthenticationValidator())
)
);
return http.build();
}
private Consumer<List<AuthenticationProvider>> configureAuthenticationValidator() {
return (authenticationProviders) ->
authenticationProviders.forEach((authenticationProvider) -> {
if (authenticationProvider instanceof OAuth2ClientCredentialsAuthenticationProvider) {
Consumer<OAuth2ClientCredentialsAuthenticationContext> authenticationValidator =
new CustomScopeValidator();
// Override default scope validation
((OAuth2ClientCredentialsAuthenticationProvider) authenticationProvider)
.setAuthenticationValidator(authenticationValidator);
}
});
}
static class CustomScopeValidator implements Consumer<OAuth2ClientCredentialsAuthenticationContext> {
@Override
public void accept(OAuth2ClientCredentialsAuthenticationContext authenticationContext) {
OAuth2ClientCredentialsAuthenticationToken clientCredentialsAuthentication =
authenticationContext.getAuthentication();
Set<String> requestedScopes = clientCredentialsAuthentication.getScopes();
RegisteredClient registeredClient = authenticationContext.getRegisteredClient();
Set<String> allowedScopes = registeredClient.getScopes();
// TODO Implement scope validation
}
}
DPoP绑定的访问Tokens
RFC 9449 OAuth 2.0 持有证明(DPoP) 是一种用于对访问Tokens施加发送方约束的应用层机制。
DPoP 的主要目标是防止未经授权或非法的客户端使用泄露或被盗的访问Tokens。其方法是在授权服务器颁发访问Tokens时,将该Tokens与一个公钥绑定,并要求客户端在资源服务器上使用该访问Tokens时,证明其拥有对应的私钥。
通过 DPoP 进行发送方约束的访问Tokens,与典型的持有者Tokens(bearer token)形成对比,后者可被任何持有该访问Tokens的客户端使用。
DPoP 引入了 DPoP 证明 的概念,这是一种由客户端创建的 JWT,并作为 HTTP 请求中的一个头部发送。 客户端使用 DPoP 证明来证明其持有与某个公钥相对应的私钥。
当客户端发起访问Tokens请求时,它会在 HTTP 请求头中附加一个 DPoP 证明。 授权服务器会将(发送方约束)访问Tokens绑定到 DPoP 证明中关联的公钥。
当客户端发起受保护资源的请求时,它会再次在 HTTP 请求头中附加一个 DPoP 证明。
资源服务器获取与访问Tokens绑定的公钥信息,该信息要么直接包含在访问Tokens中(JWT),要么通过OAuth2 Tokens内省端点获取。 随后,资源服务器验证访问Tokens所绑定的公钥是否与 DPoP 证明中的公钥相匹配。 它还会验证 DPoP 证明中的访问Tokens哈希值是否与请求中的访问Tokens一致。
DPoP 访问Tokens请求
为了请求一个通过 DPoP 绑定到公钥的访问Tokens,客户端在向 OAuth2 Tokens端点发起访问Tokens请求时,必须在 DPoP 请求头中提供有效的 DPoP 证明。
这适用于所有类型的访问Tokens请求,无论其授权许可类型如何(例如 authorization_code、refresh_token、client_credentials 等)。
以下 HTTP 请求展示了在 authorization_code 请求头中包含 DPoP 证明的 DPoP 访问Tokens请求:
POST /oauth2/token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
DPoP: eyJraWQiOiJyc2EtandrLWtpZCIsInR5cCI6ImRwb3Arand0IiwiYWxnIjoiUlMyNTYiLCJqd2siOnsia3R5IjoiUlNBIiwiZSI6IkFRQUIiLCJraWQiOiJyc2EtandrLWtpZCIsIm4iOiIzRmxxSnI1VFJza0lRSWdkRTNEZDdEOWxib1dkY1RVVDhhLWZKUjdNQXZRbTdYWE5vWWttM3Y3TVFMMU5ZdER2TDJsOENBbmMwV2RTVElOVTZJUnZjNUtxbzJRNGNzTlg5U0hPbUVmem9ST2pRcWFoRWN2ZTFqQlhsdW9DWGRZdVlweDRfMXRmUmdHNmlpNFVoeGg2aUk4cU5NSlFYLWZMZnFoYmZZZnhCUVZSUHl3QmtBYklQNHgxRUFzYkM2RlNObWtoQ3hpTU5xRWd4YUlwWThDMmtKZEpfWklWLVdXNG5vRGR6cEtxSGN3bUI4RnNydW1sVllfRE5WdlVTRElpcGlxOVBiUDRIOTlUWE4xbzc0Nm9SYU5hMDdycTFob0NnTVNTeS04NVNhZ0NveGxteUUtRC1vZjlTc01ZOE9sOXQwcmR6cG9iQnVoeUpfbzVkZnZqS3cifX0.eyJodG0iOiJQT1NUIiwiaHR1IjoiaHR0cHM6Ly9zZXJ2ZXIuZXhhbXBsZS5jb20vb2F1dGgyL3Rva2VuIiwiaWF0IjoxNzQ2ODA2MzA1LCJqdGkiOiI0YjIzNDBkMi1hOTFmLTQwYTUtYmFhOS1kZDRlNWRlYWM4NjcifQ.wq8gJ_G6vpiEinfaY3WhereqCCLoeJOG8tnWBBAzRWx9F1KU5yAAWq-ZVCk_k07-h6DIqz2wgv6y9dVbNpRYwNwDUeik9qLRsC60M8YW7EFVyI3n_NpujLwzZeub_nDYMVnyn4ii0NaZrYHtoGXOlswQfS_-ET-jpC0XWm5nBZsCdUEXjOYtwaACC6Js-pyNwKmSLp5SKIk11jZUR5xIIopaQy521y9qJHhGRwzj8DQGsP7wMZ98UFL0E--1c-hh4rTy8PMeWCqRHdwjj_ry_eTe0DJFcxxYQdeL7-0_0CIO4Ayx5WHEpcUOIzBRoN32RsNpDZc-5slDNj9ku004DA
grant_type=authorization_code\
&client_id=s6BhdRkqt\
&code=SplxlOBeZQQYbYS6WxSbIA\
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb\
&code_verifier=bEaL42izcC-o-xBk0K2vuJ6U-y1p9r_wW2dFWIWgjz-
下图展示了 DPoP Proof JWT 的头部和声明的表示形式:
{
"typ": "dpop+jwt",
"alg": "RS256",
"jwk": {
"kty": "RSA",
"e": "AQAB",
"n": "3FlqJr5TRskIQIgdE3Dd7D9lboWdcTUT8a-fJR7MAvQm7XXNoYkm3v7MQL1NYtDvL2l8CAnc0WdSTINU6IRvc5Kqo2Q4csNX9SHOmEfzoROjQqahEcve1jBXluoCXdYuYpx4_1tfRgG6ii4Uhxh6iI8qNMJQX-fLfqhbfYfxBQVRPywBkAbIP4x1EAsbC6FSNmkhCxiMNqEgxaIpY8C2kJdJ_ZIV-WW4noDdzpKqHcwmB8FsrumlVY_DNVvUSDIipiq9PbP4H99TXN1o746oRaNa07rq1hoCgMSSy-85SagCoxlmyE-D-of9SsMY8Ol9t0rdzpobBuhyJ_o5dfvjKw"
}
}
{
"htm": "POST",
"htu": "https://server.example.com/oauth2/token",
"iat": 1746806305,
"jti": "4b2340d2-a91f-40a5-baa9-dd4e5deac867"
}
以下代码展示了如何生成 DPoP Proof JWT 的示例:
RSAKey rsaKey = ...
JWKSource<SecurityContext> jwkSource = (jwkSelector, securityContext) -> jwkSelector
.select(new JWKSet(rsaKey));
NimbusJwtEncoder jwtEncoder = new NimbusJwtEncoder(jwkSource);
JwsHeader jwsHeader = JwsHeader.with(SignatureAlgorithm.RS256)
.type("dpop+jwt")
.jwk(rsaKey.toPublicJWK().toJSONObject())
.build();
JwtClaimsSet claims = JwtClaimsSet.builder()
.issuedAt(Instant.now())
.claim("htm", "POST")
.claim("htu", "https://server.example.com/oauth2/token")
.id(UUID.randomUUID().toString())
.build();
Jwt dPoPProof = jwtEncoder.encode(JwtEncoderParameters.from(jwsHeader, claims));
在授权服务器成功验证 DPoP 证明后,DPoP 证明中的公钥将被绑定(发送方受限)到所颁发的访问Tokens上。
以下访问Tokens响应将 token_type 参数显示为 DPoP,以向客户端表明该访问Tokens已绑定到其 DPoP 证明公钥:
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
{
"access_token": "Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU",
"token_type": "DPoP",
"expires_in": 2677
}
公钥确认
资源服务器必须能够识别访问Tokens是否绑定到 DPoP,并验证该Tokens与 DPoP 证明中公钥的绑定关系。 这种绑定通过将公钥以资源服务器可访问的方式与访问Tokens关联来实现,例如直接将公钥哈希嵌入访问Tokens(如 JWT)中,或通过Tokens内省(token introspection)实现。
当访问Tokens以 JWT 形式表示时,公钥哈希包含在确认方法(jkt)声明下的 cnf 声明中。
以下示例展示了包含 cnf 声明的 JWT 访问Tokens,其中 jkt 声明内又包含一个 2 声明,该声明表示 DPoP 证明公钥的 JWK SHA-256 指纹:
{
"sub":"[email protected]",
"iss":"https://server.example.com",
"nbf":1562262611,
"exp":1562266216,
"cnf":
{
"jkt":"CQMknzRoZ5YUi7vS58jck1q8TmZT8wiIiXrCN1Ny4VU"
}
}
OAuth2 Tokens内省端点
OAuth2TokenIntrospectionEndpointConfigurer 提供了自定义 OAuth2 Tokens内省端点 的能力。
它定义了扩展点,允许您自定义 OAuth2 内省请求 的预处理、主处理和后处理逻辑。
OAuth2TokenIntrospectionEndpointConfigurer 提供以下配置选项:
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
http
.oauth2AuthorizationServer((authorizationServer) ->
authorizationServer
.tokenIntrospectionEndpoint(tokenIntrospectionEndpoint ->
tokenIntrospectionEndpoint
.introspectionRequestConverter(introspectionRequestConverter) (1)
.introspectionRequestConverters(introspectionRequestConvertersConsumer) (2)
.authenticationProvider(authenticationProvider) (3)
.authenticationProviders(authenticationProvidersConsumer) (4)
.introspectionResponseHandler(introspectionResponseHandler) (5)
.errorResponseHandler(errorResponseHandler) (6)
)
);
return http.build();
}
| 1 | introspectionRequestConverter():添加一个 AuthenticationConverter(预处理器),用于在尝试从 https://datatracker.ietf.org/doc/html/rfc7662#section-2.1 中提取 OAuth2 内省请求 并转换为 OAuth2TokenIntrospectionAuthenticationToken 实例时使用。 |
| 2 | introspectionRequestConverters():设置一个 Consumer,用于访问默认的(以及可选添加的)List 列表,从而允许添加、删除或自定义特定的 AuthenticationConverter。 |
| 3 | authenticationProvider():添加一个用于对 AuthenticationProvider 进行身份验证的 OAuth2TokenIntrospectionAuthenticationToken(主处理器)。 |
| 4 | authenticationProviders():设置一个 Consumer,用于访问默认的(以及可选添加的)List 列表,从而允许添加、删除或自定义特定的 AuthenticationProvider。 |
| 5 | introspectionResponseHandler():用于处理已“认证”的 AuthenticationSuccessHandler 并返回OAuth2TokenIntrospection 响应 的 https://datatracker.ietf.org/doc/html/rfc7662#section-2.2(后处理器)。 |
| 6 | errorResponseHandler():用于处理 AuthenticationFailureHandler 并返回OAuth2Error 响应 的 https://datatracker.ietf.org/doc/html/rfc7662#section-2.3(后处理器)。 |
OAuth2TokenIntrospectionEndpointConfigurer 用于配置 OAuth2TokenIntrospectionEndpointFilter,并将其注册到 OAuth2 授权服务器的 SecurityFilterChain @Bean 中。
OAuth2TokenIntrospectionEndpointFilter 是处理 OAuth2 Tokens内省(introspection)请求的 Filter。
OAuth2TokenIntrospectionEndpointFilter 的默认配置如下:
-
AuthenticationConverter— AnOAuth2TokenIntrospectionAuthenticationConverter. -
AuthenticationManager— 一个由AuthenticationManager组成的OAuth2TokenIntrospectionAuthenticationProvider。 -
AuthenticationSuccessHandler— 一个内部实现,用于处理已“认证”的OAuth2TokenIntrospectionAuthenticationToken并返回OAuth2TokenIntrospection响应。 -
AuthenticationFailureHandler— AnOAuth2ErrorAuthenticationFailureHandler.
OAuth2 Tokens撤销端点
OAuth2TokenRevocationEndpointConfigurer 提供了自定义 OAuth2 Tokens撤销端点 的能力。
它定义了扩展点,允许您自定义 OAuth2 撤销请求 的预处理、主处理和后处理逻辑。
OAuth2TokenRevocationEndpointConfigurer 提供以下配置选项:
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
http
.oauth2AuthorizationServer((authorizationServer) ->
authorizationServer
.tokenRevocationEndpoint(tokenRevocationEndpoint ->
tokenRevocationEndpoint
.revocationRequestConverter(revocationRequestConverter) (1)
.revocationRequestConverters(revocationRequestConvertersConsumer) (2)
.authenticationProvider(authenticationProvider) (3)
.authenticationProviders(authenticationProvidersConsumer) (4)
.revocationResponseHandler(revocationResponseHandler) (5)
.errorResponseHandler(errorResponseHandler) (6)
)
);
return http.build();
}
| 1 | revocationRequestConverter():添加一个 AuthenticationConverter(预处理器),用于在尝试从 https://datatracker.ietf.org/doc/html/rfc7009#section-2.1 中提取 OAuth2 撤销请求 并转换为 OAuth2TokenRevocationAuthenticationToken 实例时使用。 |
| 2 | revocationRequestConverters():设置一个 Consumer,用于访问默认的(以及可选添加的)List 列表,从而允许添加、删除或自定义特定的 AuthenticationConverter。 |
| 3 | authenticationProvider():添加一个用于对 AuthenticationProvider 进行身份验证的 OAuth2TokenRevocationAuthenticationToken(主处理器)。 |
| 4 | authenticationProviders():设置一个 Consumer,用于访问默认的(以及可选添加的)List 列表,从而允许添加、删除或自定义特定的 AuthenticationProvider。 |
| 5 | revocationResponseHandler():用于处理“已认证”的 AuthenticationSuccessHandler 并返回OAuth2 撤销响应 的 https://datatracker.ietf.org/doc/html/rfc7009#section-2.2(后处理器)。 |
| 6 | errorResponseHandler():用于处理 AuthenticationFailureHandler 并返回OAuth2Error 响应 的 https://datatracker.ietf.org/doc/html/rfc7009#section-2.2.1(后处理器)。 |
OAuth2TokenRevocationEndpointConfigurer 用于配置 OAuth2TokenRevocationEndpointFilter,并将其注册到 OAuth2 授权服务器的 SecurityFilterChain @Bean 中。
OAuth2TokenRevocationEndpointFilter 是处理 OAuth2 撤销请求的 Filter。
OAuth2TokenRevocationEndpointFilter 的默认配置如下:
-
AuthenticationConverter— AnOAuth2TokenRevocationAuthenticationConverter. -
AuthenticationManager— 一个由AuthenticationManager组成的OAuth2TokenRevocationAuthenticationProvider。 -
AuthenticationSuccessHandler— 一个内部实现,用于处理“已认证”的OAuth2TokenRevocationAuthenticationToken并返回 OAuth2 撤销响应。 -
AuthenticationFailureHandler— AnOAuth2ErrorAuthenticationFailureHandler.
OAuth2 客户端注册端点
OAuth2ClientRegistrationEndpointConfigurer 提供了自定义 OAuth2 客户端注册端点 的能力。
它定义了扩展点,允许您自定义 客户端注册请求 的预处理、主处理和后处理逻辑。
OAuth2ClientRegistrationEndpointConfigurer 提供以下配置选项:
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
http
.oauth2AuthorizationServer((authorizationServer) ->
authorizationServer
.clientRegistrationEndpoint(clientRegistrationEndpoint ->
clientRegistrationEndpoint
.clientRegistrationRequestConverter(clientRegistrationRequestConverter) (1)
.clientRegistrationRequestConverters(clientRegistrationRequestConvertersConsumer) (2)
.authenticationProvider(authenticationProvider) (3)
.authenticationProviders(authenticationProvidersConsumer) (4)
.clientRegistrationResponseHandler(clientRegistrationResponseHandler) (5)
.errorResponseHandler(errorResponseHandler) (6)
)
);
return http.build();
}
| 1 | clientRegistrationRequestConverter():添加一个 AuthenticationConverter(预处理器),用于在尝试从 https://datatracker.ietf.org/doc/html/rfc7591#section-3.1 中提取客户端注册请求并转换为 OAuth2ClientRegistrationAuthenticationToken 实例时使用。 |
| 2 | clientRegistrationRequestConverters():设置一个 Consumer,用于访问默认的(以及可选添加的)List 列表,从而允许添加、删除或自定义特定的 AuthenticationConverter。 |
| 3 | authenticationProvider():添加一个用于对 AuthenticationProvider 进行身份验证的 OAuth2ClientRegistrationAuthenticationToken(主处理器)。 |
| 4 | authenticationProviders():设置一个 Consumer,用于访问默认的(以及可选添加的)List 列表,从而允许添加、删除或自定义特定的 AuthenticationProvider。 |
| 5 | clientRegistrationResponseHandler():用于处理“已认证”的 AuthenticationSuccessHandler 并返回客户端注册响应 的 https://datatracker.ietf.org/doc/html/rfc7591#section-3.2.1(后处理器)。 |
| 6 | errorResponseHandler():用于处理 AuthenticationFailureHandler 并返回客户端注册错误响应 的 https://datatracker.ietf.org/doc/html/rfc7591#section-3.2.2(后处理器)。 |
| OAuth2 客户端注册端点默认处于禁用状态。 |
OAuth2ClientRegistrationEndpointConfigurer 用于配置 OAuth2ClientRegistrationEndpointFilter,并将其注册到 OAuth2 授权服务器的 SecurityFilterChain @Bean 中。
OAuth2ClientRegistrationEndpointFilter 是一个 Filter,用于处理客户端注册请求并返回OAuth2ClientRegistration 响应。
OAuth2ClientRegistrationEndpointFilter 的默认配置如下:
-
AuthenticationConverter— AnOAuth2ClientRegistrationAuthenticationConverter. -
AuthenticationManager— 一个由AuthenticationManager组成的OAuth2ClientRegistrationAuthenticationProvider。 -
AuthenticationSuccessHandler— 一个内部实现,用于处理已“认证”的OAuth2ClientRegistrationAuthenticationToken并返回OAuth2ClientRegistration响应。 -
AuthenticationFailureHandler— 一个内部实现,使用与OAuth2Error关联的OAuth2AuthenticationException,并返回该OAuth2Error响应。
OAuth2 客户端注册端点是一个受 OAuth2 保护的资源,在客户端注册请求中必须以 Bearer Token 的形式发送访问Tokens。
OAuth2 资源服务器支持已自动配置,但 OAuth2 客户端注册端点必须提供一个 JwtDecoder @Bean。 |
客户端注册请求中的访问Tokens必须包含 OAuth2 范围 client.create。 |
要允许开放客户端注册(请求中无需访问Tokens),请配置 OAuth2ClientRegistrationAuthenticationProvider.setOpenRegistrationAllowed(true)。 |
OAuth2 授权服务器元数据端点
OAuth2AuthorizationServerMetadataEndpointConfigurer 提供了自定义 OAuth2 授权服务器元数据端点 的能力。
它定义了一个扩展点,允许你自定义 OAuth2 授权服务器元数据响应。
OAuth2AuthorizationServerMetadataEndpointConfigurer 提供以下配置选项:
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
http
.oauth2AuthorizationServer((authorizationServer) ->
authorizationServer
.authorizationServerMetadataEndpoint(authorizationServerMetadataEndpoint ->
authorizationServerMetadataEndpoint
.authorizationServerMetadataCustomizer(authorizationServerMetadataCustomizer) (1)
)
);
return http.build();
}
| 1 | authorizationServerMetadataCustomizer():提供对 Consumer 的访问权限的 OAuth2AuthorizationServerMetadata.Builder,可用于自定义授权服务器配置中的声明(claims)。 |
OAuth2AuthorizationServerMetadataEndpointConfigurer 用于配置 OAuth2AuthorizationServerMetadataEndpointFilter,并将其注册到 OAuth2 授权服务器的 SecurityFilterChain @Bean 中。
OAuth2AuthorizationServerMetadataEndpointFilter 是一个 Filter,用于返回 OAuth2AuthorizationServerMetadata 响应。
JWK Set 端点
OAuth2AuthorizationServerConfigurer 提供对 JWK Set 端点 的支持。
OAuth2AuthorizationServerConfigurer 配置 NimbusJwkSetEndpointFilter 并将其注册到 OAuth2 授权服务器的 SecurityFilterChain @Bean 中。
NimbusJwkSetEndpointFilter 是用于返回JWK Set 的 https://datatracker.ietf.org/doc/html/rfc7517#section-5。
JWK Set 端点仅在注册了 JWKSource<SecurityContext> 类型的 @Bean 时才会被配置。 |
OpenID Connect 1.0 提供者配置端点
OidcProviderConfigurationEndpointConfigurer 提供了自定义 OpenID Connect 1.0 提供者配置端点 的能力。
它定义了一个扩展点,允许你自定义 OpenID 提供者配置响应。
OidcProviderConfigurationEndpointConfigurer 提供以下配置选项:
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
http
.oauth2AuthorizationServer((authorizationServer) ->
authorizationServer
.oidc(oidc ->
oidc
.providerConfigurationEndpoint(providerConfigurationEndpoint ->
providerConfigurationEndpoint
.providerConfigurationCustomizer(providerConfigurationCustomizer) (1)
)
)
);
return http.build();
}
| 1 | providerConfigurationCustomizer():提供对 Consumer 访问权限的 OidcProviderConfiguration.Builder,允许自定义 OpenID 提供商配置中的声明(claims)。 |
OidcProviderConfigurationEndpointConfigurer 用于配置 OidcProviderConfigurationEndpointFilter,并将其注册到 OAuth2 授权服务器的 SecurityFilterChain @Bean 中。
OidcProviderConfigurationEndpointFilter 是一个 Filter,用于返回 OidcProviderConfiguration 响应。
OpenID Connect 1.0 注销端点
OidcLogoutEndpointConfigurer 提供了自定义 OpenID Connect 1.0 注销端点 的能力。
它定义了扩展点,允许您自定义 RP 发起的注销请求的预处理、主处理和后处理逻辑。
OidcLogoutEndpointConfigurer 提供以下配置选项:
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
http
.oauth2AuthorizationServer((authorizationServer) ->
authorizationServer
.oidc(oidc ->
oidc
.logoutEndpoint(logoutEndpoint ->
logoutEndpoint
.logoutRequestConverter(logoutRequestConverter) (1)
.logoutRequestConverters(logoutRequestConvertersConsumer) (2)
.authenticationProvider(authenticationProvider) (3)
.authenticationProviders(authenticationProvidersConsumer) (4)
.logoutResponseHandler(logoutResponseHandler) (5)
.errorResponseHandler(errorResponseHandler) (6)
)
)
);
return http.build();
}
| 1 | logoutRequestConverter():添加一个 AuthenticationConverter(预处理器),用于在尝试从 https://openid.net/specs/openid-connect-rpinitiated-1_0.html#RPLogout 中提取注销请求并转换为 OidcLogoutAuthenticationToken 实例时使用。 |
| 2 | logoutRequestConverters():设置一个 Consumer,用于访问默认的(以及可选添加的)List 列表,从而允许添加、删除或自定义特定的 AuthenticationConverter。 |
| 3 | authenticationProvider():添加一个用于对 AuthenticationProvider 进行身份验证的 OidcLogoutAuthenticationToken(主处理器)。 |
| 4 | authenticationProviders():设置一个 Consumer,用于访问默认的(以及可选添加的)List 列表,从而允许添加、删除或自定义特定的 AuthenticationProvider。 |
| 5 | logoutResponseHandler():用于处理已“认证”的 AuthenticationSuccessHandler 并执行注销操作的 OidcLogoutAuthenticationToken(后置处理器)。 |
| 6 | errorResponseHandler():用于处理 AuthenticationFailureHandler 并返回错误响应的 OAuth2AuthenticationException(后处理器)。 |
OidcLogoutEndpointConfigurer 用于配置 OidcLogoutEndpointFilter,并将其注册到 OAuth2 授权服务器的 SecurityFilterChain @Bean 中。
OidcLogoutEndpointFilter 是一个 Filter,用于处理RP 发起的注销请求并对最终用户执行注销操作。
OidcLogoutEndpointFilter 的默认配置如下:
-
AuthenticationConverter— AnOidcLogoutAuthenticationConverter. -
AuthenticationManager— 一个由AuthenticationManager组成的OidcLogoutAuthenticationProvider。 -
AuthenticationSuccessHandler— AnOidcLogoutAuthenticationSuccessHandler. -
AuthenticationFailureHandler— 一个内部实现,使用与OAuth2Error关联的OAuth2AuthenticationException,并返回该OAuth2Error响应。
OidcLogoutAuthenticationProvider 使用 SessionRegistry 查找与请求注销的终端用户关联的 SessionInformation 实例。 |
OidcClientInitiatedLogoutSuccessHandler 是 Spring Security OAuth2 客户端支持中用于配置OpenID Connect 1.0 RP 发起的注销的相应配置。 |
自定义登出请求验证
OidcLogoutAuthenticationValidator 是用于验证特定 OpenID Connect RP 发起的注销请求参数的默认验证器。
默认实现会验证 post_logout_redirect_uri 参数。
如果验证失败,将抛出一个 OAuth2AuthenticationException 异常。
OidcLogoutAuthenticationProvider 通过向 Consumer<OidcLogoutAuthenticationContext> 方法提供一个类型为 setAuthenticationValidator() 的自定义身份验证验证器,从而能够覆盖默认的注销请求验证逻辑。
OidcLogoutAuthenticationContext 持有 OidcLogoutAuthenticationToken,其中包含注销请求参数。 |
如果验证失败,身份验证验证器必须抛出OAuth2AuthenticationException。 |
以下示例展示了如何使用自定义的身份验证验证器来配置 OidcLogoutAuthenticationProvider:
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
http
.oauth2AuthorizationServer((authorizationServer) ->
authorizationServer
.oidc(oidc ->
oidc
.logoutEndpoint(logoutEndpoint ->
logoutEndpoint
.authenticationProviders(configureAuthenticationValidator())
)
)
);
return http.build();
}
private Consumer<List<AuthenticationProvider>> configureAuthenticationValidator() {
return (authenticationProviders) ->
authenticationProviders.forEach((authenticationProvider) -> {
if (authenticationProvider instanceof OidcLogoutAuthenticationProvider oidcLogoutAuthenticationProvider) {
Consumer<OidcLogoutAuthenticationContext> authenticationValidator = new CustomPostLogoutRedirectUriValidator();
oidcLogoutAuthenticationProvider.setAuthenticationValidator(authenticationValidator);
}
});
}
static class CustomPostLogoutRedirectUriValidator implements Consumer<OidcLogoutAuthenticationContext> {
@Override
public void accept(OidcLogoutAuthenticationContext authenticationContext) {
OidcLogoutAuthenticationToken oidcLogoutAuthentication =
authenticationContext.getAuthentication();
RegisteredClient registeredClient = authenticationContext.getRegisteredClient();
// TODO
}
}
OpenID Connect 1.0 用户信息(UserInfo)端点
OidcUserInfoEndpointConfigurer 提供了自定义 OpenID Connect 1.0 UserInfo 端点 的能力。
它定义了扩展点,允许您自定义 UserInfo 请求 的预处理、主处理和后处理逻辑。
OidcUserInfoEndpointConfigurer 提供以下配置选项:
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
http
.oauth2AuthorizationServer((authorizationServer) ->
authorizationServer
.oidc(oidc ->
oidc
.userInfoEndpoint(userInfoEndpoint ->
userInfoEndpoint
.userInfoRequestConverter(userInfoRequestConverter) (1)
.userInfoRequestConverters(userInfoRequestConvertersConsumer) (2)
.authenticationProvider(authenticationProvider) (3)
.authenticationProviders(authenticationProvidersConsumer) (4)
.userInfoResponseHandler(userInfoResponseHandler) (5)
.errorResponseHandler(errorResponseHandler) (6)
.userInfoMapper(userInfoMapper) (7)
)
)
);
return http.build();
}
| 1 | userInfoRequestConverter():添加一个 AuthenticationConverter(预处理器),用于在尝试从 https://openid.net/specs/openid-connect-core-1_0.html#UserInfoRequest 中提取 UserInfo 请求 并转换为 OidcUserInfoAuthenticationToken 实例时使用。 |
| 2 | userInfoRequestConverters():设置一个 Consumer,用于访问默认的(以及可选添加的)List 列表,从而允许添加、删除或自定义特定的 AuthenticationConverter。 |
| 3 | authenticationProvider():添加一个用于对 AuthenticationProvider 进行身份验证的 OidcUserInfoAuthenticationToken(主处理器)。 |
| 4 | authenticationProviders():设置一个 Consumer,用于访问默认的(以及可选添加的)List 列表,从而允许添加、删除或自定义特定的 AuthenticationProvider。 |
| 5 | userInfoResponseHandler():用于处理已“认证”的 AuthenticationSuccessHandler 并返回UserInfo 响应 的 https://openid.net/specs/openid-connect-core-1_0.html#UserInfoResponse(后处理器)。 |
| 6 | errorResponseHandler():用于处理 AuthenticationFailureHandler 并返回UserInfo 错误响应 的 https://openid.net/specs/openid-connect-core-1_0.html#UserInfoError(后处理器)。 |
| 7 | userInfoMapper():用于从 Function 中提取声明(claims)并映射为 OidcUserInfoAuthenticationContext 实例的 OidcUserInfo。 |
OidcUserInfoEndpointConfigurer 用于配置 OidcUserInfoEndpointFilter,并将其注册到 OAuth2 授权服务器的 SecurityFilterChain @Bean 中。
OidcUserInfoEndpointFilter 是一个 Filter,用于处理UserInfo 请求并返回OidcUserInfo 响应。
OidcUserInfoEndpointFilter 的默认配置如下:
-
AuthenticationConverter— 一个内部实现,用于从Authentication中获取SecurityContext,并使用主体(principal)创建一个OidcUserInfoAuthenticationToken。 -
AuthenticationManager— 一个由AuthenticationManager组成的OidcUserInfoAuthenticationProvider,它关联了一个内部实现的userInfoMapper,该实现会根据授权过程中请求的 scopes,从ID Token中提取标准声明(standard claims)。 -
AuthenticationSuccessHandler— 一个内部实现,用于处理已“认证”的OidcUserInfoAuthenticationToken并返回OidcUserInfo响应。 -
AuthenticationFailureHandler— 一个内部实现,使用与OAuth2Error关联的OAuth2AuthenticationException,并返回该OAuth2Error响应。
您可以通过提供 OAuth2TokenCustomizer<JwtEncodingContext> @Bean 来自定义 ID Tokens。 |
OpenID Connect 1.0 的 UserInfo 端点是一个受 OAuth2 保护的资源,必须在UserInfo 请求中以 Bearer Token 的形式发送访问Tokens。
OAuth2 资源服务器支持是自动配置的,但是,要使用 OpenID Connect 1.0 的 UserInfo 端点,必须提供一个 JwtDecoder @Bean。 |
OpenID Connect 1.0 客户端注册端点
OidcClientRegistrationEndpointConfigurer 提供了自定义 OpenID Connect 1.0 客户端注册端点 的能力。
它定义了扩展点,允许您自定义 客户端注册请求 或 客户端读取请求 的预处理、主处理和后处理逻辑。
OidcClientRegistrationEndpointConfigurer 提供以下配置选项:
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
http
.oauth2AuthorizationServer((authorizationServer) ->
authorizationServer
.oidc(oidc ->
oidc
.clientRegistrationEndpoint(clientRegistrationEndpoint ->
clientRegistrationEndpoint
.clientRegistrationRequestConverter(clientRegistrationRequestConverter) (1)
.clientRegistrationRequestConverters(clientRegistrationRequestConvertersConsumers) (2)
.authenticationProvider(authenticationProvider) (3)
.authenticationProviders(authenticationProvidersConsumer) (4)
.clientRegistrationResponseHandler(clientRegistrationResponseHandler) (5)
.errorResponseHandler(errorResponseHandler) (6)
)
)
);
return http.build();
}
| 1 | clientRegistrationRequestConverter():添加一个 AuthenticationConverter(预处理器),用于在尝试从 https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationRequest 中提取客户端注册请求或客户端读取请求并转换为 OidcClientRegistrationAuthenticationToken 实例时使用。 |
| 2 | clientRegistrationRequestConverters():设置一个 Consumer,用于访问默认的(以及可选添加的)List 列表,从而允许添加、删除或自定义特定的 AuthenticationConverter。 |
| 3 | authenticationProvider():添加一个用于对 AuthenticationProvider 进行身份验证的 OidcClientRegistrationAuthenticationToken(主处理器)。 |
| 4 | authenticationProviders():设置一个 Consumer,用于访问默认的(以及可选添加的)List 列表,从而允许添加、删除或自定义特定的 AuthenticationProvider。 |
| 5 | clientRegistrationResponseHandler():用于处理已“认证”的 AuthenticationSuccessHandler 并返回客户端注册响应或客户端读取响应的 https://openid.net/specs/openid-connect-registration-1_0.html#ReadResponse(后处理器)。 |
| 6 | errorResponseHandler():用于处理 AuthenticationFailureHandler 并返回客户端注册错误响应或客户端读取错误响应的 https://openid.net/specs/openid-connect-registration-1_0.html#ReadError(后处理器)。 |
| OpenID Connect 1.0 客户端注册端点默认处于禁用状态。 |
OidcClientRegistrationEndpointConfigurer 用于配置 OidcClientRegistrationEndpointFilter,并将其注册到 OAuth2 授权服务器的 SecurityFilterChain @Bean 中。
OidcClientRegistrationEndpointFilter 是一个 Filter,用于处理客户端注册请求并返回OidcClientRegistration 响应。
OidcClientRegistrationEndpointFilter 还会处理客户端读取请求,并返回OidcClientRegistration 响应。 |
OidcClientRegistrationEndpointFilter 的默认配置如下:
-
AuthenticationConverter— AnOidcClientRegistrationAuthenticationConverter. -
AuthenticationManager— 一个由AuthenticationManager和OidcClientRegistrationAuthenticationProvider组成的OidcClientConfigurationAuthenticationProvider。 -
AuthenticationSuccessHandler— 一个内部实现,用于处理已“认证”的OidcClientRegistrationAuthenticationToken并返回OidcClientRegistration响应。 -
AuthenticationFailureHandler— 一个内部实现,使用与OAuth2Error关联的OAuth2AuthenticationException,并返回该OAuth2Error响应。
OpenID Connect 1.0 客户端注册端点是一个受 OAuth2 保护的资源,在客户端注册(或客户端读取)请求中必须以 Bearer Token 的形式发送访问Tokens。
OAuth2 资源服务器支持是自动配置的,但是,对于 OpenID Connect 1.0 客户端注册端点,必须提供一个 JwtDecoder @Bean。 |
客户端注册请求中的访问Tokens必须包含 OAuth2 范围 client.create。 |
客户端读取请求中的访问Tokens必须包含 OAuth2 范围 client.read。 |