协议端点
OAuth2 授权端点
OAuth2AuthorizationEndpointConfigurer 提供了自定义 OAuth2 授权端点 的能力。它定义了扩展点,允许您自定义 OAuth2 授权请求 的预处理、主处理和后处理逻辑。
OAuth2AuthorizationEndpointConfigurer 提供了以下配置选项
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (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 (预处理器),用于尝试将 OAuth2 授权请求 (或同意) 从 HttpServletRequest 提取到 OAuth2AuthorizationCodeRequestAuthenticationToken 或 OAuth2AuthorizationConsentAuthenticationToken 实例。 |
| 2 | authorizationRequestConverters():设置 Consumer,提供对默认和(可选)添加的 AuthenticationConverter 列表的访问,允许添加、删除或自定义特定的 AuthenticationConverter。 |
| 3 | authenticationProvider():添加一个 AuthenticationProvider (主处理器),用于验证 OAuth2AuthorizationCodeRequestAuthenticationToken 或 OAuth2AuthorizationConsentAuthenticationToken。 |
| 4 | authenticationProviders():设置 Consumer,提供对默认和(可选)添加的 AuthenticationProvider 列表的访问,允许添加、删除或自定义特定的 AuthenticationProvider。 |
| 5 | authorizationResponseHandler():AuthenticationSuccessHandler (后处理器),用于处理“已认证”的 OAuth2AuthorizationCodeRequestAuthenticationToken 并返回 OAuth2AuthorizationResponse。 |
| 6 | errorResponseHandler():AuthenticationFailureHandler (后处理器),用于处理 OAuth2AuthorizationCodeRequestAuthenticationException 并返回 OAuth2Error 响应。 |
| 7 | consentPage():自定义同意页面的 URI,如果授权请求流程中需要同意,则重定向资源所有者到该页面。 |
OAuth2AuthorizationEndpointConfigurer 配置 OAuth2AuthorizationEndpointFilter 并将其注册到 OAuth2 授权服务器 SecurityFilterChain @Bean。OAuth2AuthorizationEndpointFilter 是处理 OAuth2 授权请求(和同意)的 Filter。
OAuth2AuthorizationEndpointFilter 配置了以下默认值
-
AuthenticationConverter— 由OAuth2AuthorizationCodeRequestAuthenticationConverter和OAuth2AuthorizationConsentAuthenticationConverter组成的DelegatingAuthenticationConverter。 -
AuthenticationManager— 由OAuth2AuthorizationCodeRequestAuthenticationProvider和OAuth2AuthorizationConsentAuthenticationProvider组成的AuthenticationManager。 -
AuthenticationSuccessHandler— 一个内部实现,用于处理“已认证”的OAuth2AuthorizationCodeRequestAuthenticationToken并返回OAuth2AuthorizationResponse。 -
AuthenticationFailureHandler— 一个内部实现,它使用与OAuth2AuthorizationCodeRequestAuthenticationException关联的OAuth2Error并返回OAuth2Error响应。
自定义授权请求验证
OAuth2AuthorizationCodeRequestAuthenticationValidator 是用于验证授权码授权中特定 OAuth2 授权请求参数的默认验证器。默认实现验证 redirect_uri 和 scope 参数。如果验证失败,将抛出 OAuth2AuthorizationCodeRequestAuthenticationException。
OAuth2AuthorizationCodeRequestAuthenticationProvider 通过向 setAuthenticationValidator() 提供类型为 Consumer<OAuth2AuthorizationCodeRequestAuthenticationContext> 的自定义身份验证验证器,提供了覆盖默认授权请求验证的能力。
OAuth2AuthorizationCodeRequestAuthenticationContext 包含 OAuth2AuthorizationCodeRequestAuthenticationToken,其中包含 OAuth2 授权请求参数。 |
如果验证失败,身份验证验证器 必须 抛出 OAuth2AuthorizationCodeRequestAuthenticationException。 |
在开发生命周期阶段,一个常见的用例是允许 redirect_uri 参数中的 localhost。
以下示例展示了如何使用自定义身份验证验证器配置 OAuth2AuthorizationCodeRequestAuthenticationProvider,该验证器允许 redirect_uri 参数中的 localhost
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (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 {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (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 (预处理器),用于尝试将 OAuth2 推送授权请求 从 HttpServletRequest 提取到 OAuth2PushedAuthorizationRequestAuthenticationToken 实例。 |
| 2 | pushedAuthorizationRequestConverters():设置 Consumer,提供对默认和(可选)添加的 AuthenticationConverter 列表的访问,允许添加、删除或自定义特定的 AuthenticationConverter。 |
| 3 | authenticationProvider():添加一个 AuthenticationProvider (主处理器),用于验证 OAuth2PushedAuthorizationRequestAuthenticationToken。 |
| 4 | authenticationProviders():设置 Consumer,提供对默认和(可选)添加的 AuthenticationProvider 列表的访问,允许添加、删除或自定义特定的 AuthenticationProvider。 |
| 5 | pushedAuthorizationResponseHandler():AuthenticationSuccessHandler (后处理器),用于处理“已认证”的 OAuth2PushedAuthorizationRequestAuthenticationToken 并返回 OAuth2 推送授权响应。 |
| 6 | errorResponseHandler():AuthenticationFailureHandler (后处理器),用于处理 OAuth2AuthenticationException 并返回 OAuth2Error 响应。 |
OAuth2PushedAuthorizationRequestEndpointConfigurer 配置 OAuth2PushedAuthorizationRequestEndpointFilter 并将其注册到 OAuth2 授权服务器 SecurityFilterChain @Bean。OAuth2PushedAuthorizationRequestEndpointFilter 是处理 OAuth2 推送授权请求的 Filter。
OAuth2PushedAuthorizationRequestEndpointFilter 配置了以下默认值
-
AuthenticationConverter— 由OAuth2AuthorizationCodeRequestAuthenticationConverter组成的DelegatingAuthenticationConverter。 -
AuthenticationManager— 由OAuth2PushedAuthorizationRequestAuthenticationProvider组成的AuthenticationManager。 -
AuthenticationSuccessHandler— 一个内部实现,用于处理“已认证”的OAuth2PushedAuthorizationRequestAuthenticationToken并返回 OAuth2 推送授权响应。 -
AuthenticationFailureHandler— 一个OAuth2ErrorAuthenticationFailureHandler。
自定义推送授权请求验证
OAuth2AuthorizationCodeRequestAuthenticationValidator 是用于验证授权码授权中特定 OAuth2 推送授权请求参数的默认验证器。默认实现验证 redirect_uri 和 scope 参数。如果验证失败,将抛出 OAuth2AuthorizationCodeRequestAuthenticationException。
OAuth2PushedAuthorizationRequestAuthenticationProvider 通过向 setAuthenticationValidator() 提供类型为 Consumer<OAuth2AuthorizationCodeRequestAuthenticationContext> 的自定义身份验证验证器,提供了覆盖默认推送授权请求验证的能力。
OAuth2AuthorizationCodeRequestAuthenticationContext 包含 OAuth2AuthorizationCodeRequestAuthenticationToken,其中包含 OAuth2 推送授权请求参数。 |
如果验证失败,身份验证验证器 必须 抛出 OAuth2AuthorizationCodeRequestAuthenticationException。 |
在开发生命周期阶段,一个常见的用例是允许 redirect_uri 参数中的 localhost。
以下示例展示了如何使用自定义身份验证验证器配置 OAuth2PushedAuthorizationRequestAuthenticationProvider,该验证器允许 redirect_uri 参数中的 localhost
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (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 {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (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 (预处理器),用于尝试将 OAuth2 设备授权请求 从 HttpServletRequest 提取到 OAuth2DeviceAuthorizationRequestAuthenticationToken 实例。 |
| 2 | deviceAuthorizationRequestConverters():设置 Consumer,提供对默认和(可选)添加的 AuthenticationConverter 列表的访问,允许添加、删除或自定义特定的 AuthenticationConverter。 |
| 3 | authenticationProvider():添加一个 AuthenticationProvider (主处理器),用于验证 OAuth2DeviceAuthorizationRequestAuthenticationToken。 |
| 4 | authenticationProviders():设置 Consumer,提供对默认和(可选)添加的 AuthenticationProvider 列表的访问,允许添加、删除或自定义特定的 AuthenticationProvider。 |
| 5 | deviceAuthorizationResponseHandler():AuthenticationSuccessHandler (后处理器),用于处理“已认证”的 OAuth2DeviceAuthorizationRequestAuthenticationToken 并返回 OAuth2DeviceAuthorizationResponse。 |
| 6 | errorResponseHandler():AuthenticationFailureHandler (后处理器),用于处理 OAuth2AuthenticationException 并返回 OAuth2Error 响应。 |
| 7 | verificationUri():自定义终端用户验证页面的 URI,用于在辅助设备上引导资源所有者。 |
OAuth2DeviceAuthorizationEndpointConfigurer 配置 OAuth2DeviceAuthorizationEndpointFilter 并将其注册到 OAuth2 授权服务器 SecurityFilterChain @Bean。OAuth2DeviceAuthorizationEndpointFilter 是处理 OAuth2 设备授权请求的 Filter。
OAuth2DeviceAuthorizationEndpointFilter 配置了以下默认值
-
AuthenticationConverter— 一个OAuth2DeviceAuthorizationRequestAuthenticationConverter。 -
AuthenticationManager— 由OAuth2DeviceAuthorizationRequestAuthenticationProvider组成的AuthenticationManager。 -
AuthenticationSuccessHandler— 一个内部实现,用于处理“已认证”的OAuth2DeviceAuthorizationRequestAuthenticationToken并返回OAuth2DeviceAuthorizationResponse。 -
AuthenticationFailureHandler— 一个OAuth2ErrorAuthenticationFailureHandler。
OAuth2 设备验证端点
OAuth2DeviceVerificationEndpointConfigurer 提供了自定义 OAuth2 设备验证端点 (或“用户交互”) 的能力。它定义了扩展点,允许您自定义 OAuth2 设备验证请求的预处理、主处理和后处理逻辑。
OAuth2DeviceVerificationEndpointConfigurer 提供了以下配置选项
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (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 (预处理器),用于尝试将 OAuth2 设备验证请求 (或同意) 从 HttpServletRequest 提取到 OAuth2DeviceVerificationAuthenticationToken 或 OAuth2DeviceAuthorizationConsentAuthenticationToken 实例。 |
| 2 | deviceVerificationRequestConverters():设置 Consumer,提供对默认和(可选)添加的 AuthenticationConverter 列表的访问,允许添加、删除或自定义特定的 AuthenticationConverter。 |
| 3 | authenticationProvider():添加一个 AuthenticationProvider (主处理器),用于验证 OAuth2DeviceVerificationAuthenticationToken 或 OAuth2DeviceAuthorizationConsentAuthenticationToken。 |
| 4 | authenticationProviders():设置 Consumer,提供对默认和(可选)添加的 AuthenticationProvider 列表的访问,允许添加、删除或自定义特定的 AuthenticationProvider。 |
| 5 | deviceVerificationResponseHandler():AuthenticationSuccessHandler (后处理器),用于处理“已认证”的 OAuth2DeviceVerificationAuthenticationToken 并引导资源所有者返回其设备。 |
| 6 | errorResponseHandler():AuthenticationFailureHandler (后处理器),用于处理 OAuth2AuthenticationException 并返回错误响应。 |
| 7 | consentPage():自定义同意页面的 URI,如果设备验证请求流程中需要同意,则重定向资源所有者到该页面。 |
OAuth2DeviceVerificationEndpointConfigurer 配置 OAuth2DeviceVerificationEndpointFilter 并将其注册到 OAuth2 授权服务器 SecurityFilterChain @Bean。OAuth2DeviceVerificationEndpointFilter 是处理 OAuth2 设备验证请求(和同意)的 Filter。
OAuth2DeviceVerificationEndpointFilter 配置了以下默认值
-
AuthenticationConverter— 由OAuth2DeviceVerificationAuthenticationConverter和OAuth2DeviceAuthorizationConsentAuthenticationConverter组成的DelegatingAuthenticationConverter。 -
AuthenticationManager— 由OAuth2DeviceVerificationAuthenticationProvider和OAuth2DeviceAuthorizationConsentAuthenticationProvider组成的AuthenticationManager。 -
AuthenticationSuccessHandler— 一个SimpleUrlAuthenticationSuccessHandler,用于处理“已认证”的OAuth2DeviceVerificationAuthenticationToken并将用户重定向到成功页面(/?success)。 -
AuthenticationFailureHandler— 一个内部实现,它使用与OAuth2AuthenticationException关联的OAuth2Error并返回OAuth2Error响应。
OAuth2 令牌端点
OAuth2TokenEndpointConfigurer 提供了自定义 OAuth2 令牌端点 的能力。它定义了扩展点,允许您自定义 OAuth2 访问令牌请求 的预处理、主处理和后处理逻辑。
OAuth2TokenEndpointConfigurer 提供了以下配置选项
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (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 (预处理器),用于尝试将 OAuth2 访问令牌请求 从 HttpServletRequest 提取到 OAuth2AuthorizationGrantAuthenticationToken 实例。 |
| 2 | accessTokenRequestConverters():设置 Consumer,提供对默认和(可选)添加的 AuthenticationConverter 列表的访问,允许添加、删除或自定义特定的 AuthenticationConverter。 |
| 3 | authenticationProvider():添加一个 AuthenticationProvider (主处理器),用于验证 OAuth2AuthorizationGrantAuthenticationToken。 |
| 4 | authenticationProviders():设置 Consumer,提供对默认和(可选)添加的 AuthenticationProvider 列表的访问,允许添加、删除或自定义特定的 AuthenticationProvider。 |
| 5 | accessTokenResponseHandler():AuthenticationSuccessHandler (后处理器),用于处理 OAuth2AccessTokenAuthenticationToken 并返回 OAuth2AccessTokenResponse。 |
| 6 | errorResponseHandler():AuthenticationFailureHandler (后处理器),用于处理 OAuth2AuthenticationException 并返回 OAuth2Error 响应。 |
OAuth2TokenEndpointConfigurer 配置 OAuth2TokenEndpointFilter 并将其注册到 OAuth2 授权服务器 SecurityFilterChain @Bean。OAuth2TokenEndpointFilter 是处理 OAuth2 访问令牌请求的 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— 由OAuth2AuthorizationCodeAuthenticationConverter、OAuth2RefreshTokenAuthenticationConverter、OAuth2ClientCredentialsAuthenticationConverter、OAuth2DeviceCodeAuthenticationConverter和OAuth2TokenExchangeAuthenticationConverter组成的DelegatingAuthenticationConverter。 -
AuthenticationManager— 由OAuth2AuthorizationCodeAuthenticationProvider、OAuth2RefreshTokenAuthenticationProvider、OAuth2ClientCredentialsAuthenticationProvider、OAuth2DeviceCodeAuthenticationProvider和OAuth2TokenExchangeAuthenticationProvider组成的AuthenticationManager。 -
AuthenticationSuccessHandler— 一个OAuth2AccessTokenResponseAuthenticationSuccessHandler。 -
AuthenticationFailureHandler— 一个OAuth2ErrorAuthenticationFailureHandler。
自定义客户端凭证授权请求验证
OAuth2ClientCredentialsAuthenticationValidator 是用于验证特定 OAuth2 客户端凭证授权请求参数的默认验证器。默认实现验证 scope 参数。如果验证失败,将抛出 OAuth2AuthenticationException。
OAuth2ClientCredentialsAuthenticationProvider 通过向 setAuthenticationValidator() 提供类型为 Consumer<OAuth2ClientCredentialsAuthenticationContext> 的自定义身份验证验证器,提供了覆盖默认请求验证的能力。
OAuth2ClientCredentialsAuthenticationContext 包含 OAuth2ClientCredentialsAuthenticationToken,其中包含 OAuth2 客户端凭证授权请求参数。 |
如果验证失败,身份验证验证器 必须 抛出 OAuth2AuthenticationException。 |
以下示例展示了如何使用自定义身份验证验证器配置 OAuth2ClientCredentialsAuthenticationProvider,该验证器覆盖了默认的 scope 验证
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (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 绑定的访问令牌
RFC 9449 OAuth 2.0 证明持有(DPoP)是一种用于发送方约束访问令牌的应用层机制。
DPoP 的主要目标是通过授权服务器在颁发访问令牌时将其绑定到公钥,并要求客户端在使用访问令牌访问资源服务器时证明持有相应的私钥,从而防止未经授权或非法的客户端使用泄露或被盗的访问令牌。
通过 DPoP 进行发送方约束的访问令牌与典型的持有者令牌(任何持有访问令牌的客户端都可以使用)形成对比。
DPoP 引入了 DPoP 证明的概念,它是由客户端创建并作为 HTTP 请求头发送的 JWT。客户端使用 DPoP 证明来证明持有与特定公钥对应的私钥。
当客户端发起访问令牌请求时,它会在 HTTP 头中附加 DPoP 证明。授权服务器将访问令牌绑定(发送方约束)到 DPoP 证明中关联的公钥。
当客户端发起受保护资源请求时,它再次在 HTTP 头中附加 DPoP 证明。
资源服务器获取与访问令牌绑定的公钥信息,可以直接从访问令牌(JWT)中获取,也可以通过 OAuth2 令牌自省端点 获取。然后,资源服务器验证与访问令牌绑定的公钥是否与 DPoP 证明中的公钥匹配。它还验证 DPoP 证明中的访问令牌哈希是否与请求中的访问令牌匹配。
DPoP 访问令牌请求
要使用 DPoP 请求绑定到公钥的访问令牌,客户端在向 OAuth2 令牌端点发出访问令牌请求时,必须 在 DPoP 头中提供有效的 DPoP 证明。这适用于所有访问令牌请求,无论授权类型如何(例如 authorization_code、refresh_token、client_credentials 等)。
以下 HTTP 请求显示了一个在 DPoP 头中包含 DPoP 证明的 authorization_code 访问令牌请求
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 证明 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 证明 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 证明中的公钥将被绑定(发送方约束)到颁发的访问令牌。
以下访问令牌响应显示 token_type 参数为 DPoP,以向客户端表明访问令牌已绑定到其 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
}
公钥确认
资源服务器必须能够识别访问令牌是否为 DPoP 绑定,并验证与 DPoP 证明公钥的绑定。绑定是通过将公钥与访问令牌关联起来,以便资源服务器可以访问,例如直接在访问令牌中嵌入公钥哈希(JWT)或通过令牌内省。
当访问令牌表示为 JWT 时,公钥哈希包含在确认方法(cnf)声明下的 jkt 声明中。
以下示例显示了包含 cnf 声明和 jkt 声明的 JWT 访问令牌的声明,其中 jkt 是 DPoP 证明公钥的 JWK SHA-256 指纹
{
"sub":"[email protected]",
"iss":"https://server.example.com",
"nbf":1562262611,
"exp":1562266216,
"cnf":
{
"jkt":"CQMknzRoZ5YUi7vS58jck1q8TmZT8wiIiXrCN1Ny4VU"
}
}
OAuth2 令牌自省端点
OAuth2TokenIntrospectionEndpointConfigurer 提供了自定义 OAuth2 令牌自省端点 的能力。它定义了扩展点,允许您自定义 OAuth2 自省请求 的预处理、主处理和后处理逻辑。
OAuth2TokenIntrospectionEndpointConfigurer 提供了以下配置选项
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (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 (预处理器),用于尝试将 OAuth2 自省请求 从 HttpServletRequest 提取到 OAuth2TokenIntrospectionAuthenticationToken 实例。 |
| 2 | introspectionRequestConverters():设置 Consumer,提供对默认和(可选)添加的 AuthenticationConverter 列表的访问,允许添加、删除或自定义特定的 AuthenticationConverter。 |
| 3 | authenticationProvider():添加一个 AuthenticationProvider (主处理器),用于验证 OAuth2TokenIntrospectionAuthenticationToken。 |
| 4 | authenticationProviders():设置 Consumer,提供对默认和(可选)添加的 AuthenticationProvider 列表的访问,允许添加、删除或自定义特定的 AuthenticationProvider。 |
| 5 | introspectionResponseHandler():AuthenticationSuccessHandler (后处理器),用于处理“已认证”的 OAuth2TokenIntrospectionAuthenticationToken 并返回 OAuth2TokenIntrospection 响应。 |
| 6 | errorResponseHandler():AuthenticationFailureHandler (后处理器),用于处理 OAuth2AuthenticationException 并返回 OAuth2Error 响应。 |
OAuth2TokenIntrospectionEndpointConfigurer 配置 OAuth2TokenIntrospectionEndpointFilter 并将其注册到 OAuth2 授权服务器 SecurityFilterChain @Bean。OAuth2TokenIntrospectionEndpointFilter 是处理 OAuth2 自省请求的 Filter。
OAuth2TokenIntrospectionEndpointFilter 配置了以下默认值
-
AuthenticationConverter— 一个OAuth2TokenIntrospectionAuthenticationConverter。 -
AuthenticationManager— 由OAuth2TokenIntrospectionAuthenticationProvider组成的AuthenticationManager。 -
AuthenticationSuccessHandler— 一个内部实现,用于处理“已认证”的OAuth2TokenIntrospectionAuthenticationToken并返回OAuth2TokenIntrospection响应。 -
AuthenticationFailureHandler— 一个OAuth2ErrorAuthenticationFailureHandler。
OAuth2 令牌撤销端点
OAuth2TokenRevocationEndpointConfigurer 提供了自定义 OAuth2 令牌撤销端点 的能力。它定义了扩展点,允许您自定义 OAuth2 撤销请求 的预处理、主处理和后处理逻辑。
OAuth2TokenRevocationEndpointConfigurer 提供了以下配置选项
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (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 (预处理器),用于尝试将 OAuth2 撤销请求 从 HttpServletRequest 提取到 OAuth2TokenRevocationAuthenticationToken 实例。 |
| 2 | revocationRequestConverters():设置 Consumer,提供对默认和(可选)添加的 AuthenticationConverter 列表的访问,允许添加、删除或自定义特定的 AuthenticationConverter。 |
| 3 | authenticationProvider():添加一个 AuthenticationProvider (主处理器),用于验证 OAuth2TokenRevocationAuthenticationToken。 |
| 4 | authenticationProviders():设置 Consumer,提供对默认和(可选)添加的 AuthenticationProvider 列表的访问,允许添加、删除或自定义特定的 AuthenticationProvider。 |
| 5 | revocationResponseHandler():AuthenticationSuccessHandler (后处理器),用于处理“已认证”的 OAuth2TokenRevocationAuthenticationToken 并返回 OAuth2 撤销响应。 |
| 6 | errorResponseHandler():AuthenticationFailureHandler (后处理器),用于处理 OAuth2AuthenticationException 并返回 OAuth2Error 响应。 |
OAuth2TokenRevocationEndpointConfigurer 配置 OAuth2TokenRevocationEndpointFilter 并将其注册到 OAuth2 授权服务器 SecurityFilterChain @Bean。OAuth2TokenRevocationEndpointFilter 是处理 OAuth2 撤销请求的 Filter。
OAuth2TokenRevocationEndpointFilter 配置了以下默认值
-
AuthenticationConverter— 一个OAuth2TokenRevocationAuthenticationConverter。 -
AuthenticationManager— 由OAuth2TokenRevocationAuthenticationProvider组成的AuthenticationManager。 -
AuthenticationSuccessHandler— 一个内部实现,用于处理“已认证”的OAuth2TokenRevocationAuthenticationToken并返回 OAuth2 撤销响应。 -
AuthenticationFailureHandler— 一个OAuth2ErrorAuthenticationFailureHandler。
OAuth2 授权服务器元数据端点
OAuth2AuthorizationServerMetadataEndpointConfigurer 提供了自定义 OAuth2 授权服务器元数据端点 的能力。它定义了一个扩展点,允许您自定义 OAuth2 授权服务器元数据响应。
OAuth2AuthorizationServerMetadataEndpointConfigurer 提供了以下配置选项
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.authorizationServerMetadataEndpoint(authorizationServerMetadataEndpoint ->
authorizationServerMetadataEndpoint
.authorizationServerMetadataCustomizer(authorizationServerMetadataCustomizer) (1)
)
);
return http.build();
}
| 1 | authorizationServerMetadataCustomizer():Consumer,提供对 OAuth2AuthorizationServerMetadata.Builder 的访问,允许自定义授权服务器配置的声明。 |
OAuth2AuthorizationServerMetadataEndpointConfigurer 配置 OAuth2AuthorizationServerMetadataEndpointFilter 并将其注册到 OAuth2 授权服务器 SecurityFilterChain @Bean。OAuth2AuthorizationServerMetadataEndpointFilter 是返回 OAuth2AuthorizationServerMetadata 响应 的 Filter。
OpenID Connect 1.0 提供者配置端点
OidcProviderConfigurationEndpointConfigurer 提供了自定义 OpenID Connect 1.0 提供者配置端点 的能力。它定义了一个扩展点,允许您自定义 OpenID 提供者配置响应。
OidcProviderConfigurationEndpointConfigurer 提供了以下配置选项
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.oidc(oidc ->
oidc
.providerConfigurationEndpoint(providerConfigurationEndpoint ->
providerConfigurationEndpoint
.providerConfigurationCustomizer(providerConfigurationCustomizer) (1)
)
)
);
return http.build();
}
| 1 | providerConfigurationCustomizer():Consumer,提供对 OidcProviderConfiguration.Builder 的访问,允许自定义 OpenID 提供者配置的声明。 |
OidcProviderConfigurationEndpointConfigurer 配置 OidcProviderConfigurationEndpointFilter 并将其注册到 OAuth2 授权服务器 SecurityFilterChain @Bean。OidcProviderConfigurationEndpointFilter 是返回 OidcProviderConfiguration 响应 的 Filter。
OpenID Connect 1.0 注销端点
OidcLogoutEndpointConfigurer 提供了自定义 OpenID Connect 1.0 注销端点 的能力。它定义了扩展点,允许您自定义 RP 发起的注销请求的预处理、主处理和后处理逻辑。
OidcLogoutEndpointConfigurer 提供了以下配置选项
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (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 (预处理器),用于尝试将 注销请求 从 HttpServletRequest 提取到 OidcLogoutAuthenticationToken 实例。 |
| 2 | logoutRequestConverters():设置 Consumer,提供对默认和(可选)添加的 AuthenticationConverter 列表的访问,允许添加、删除或自定义特定的 AuthenticationConverter。 |
| 3 | authenticationProvider():添加一个 AuthenticationProvider (主处理器),用于验证 OidcLogoutAuthenticationToken。 |
| 4 | authenticationProviders():设置 Consumer,提供对默认和(可选)添加的 AuthenticationProvider 列表的访问,允许添加、删除或自定义特定的 AuthenticationProvider。 |
| 5 | logoutResponseHandler():AuthenticationSuccessHandler (后处理器),用于处理“已认证”的 OidcLogoutAuthenticationToken 并执行注销。 |
| 6 | errorResponseHandler():AuthenticationFailureHandler (后处理器),用于处理 OAuth2AuthenticationException 并返回错误响应。 |
OidcLogoutEndpointConfigurer 配置 OidcLogoutEndpointFilter 并将其注册到 OAuth2 授权服务器 SecurityFilterChain @Bean。OidcLogoutEndpointFilter 是处理 RP 发起的注销请求 并执行终端用户注销的 Filter。
OidcLogoutEndpointFilter 配置了以下默认值
-
AuthenticationConverter— 一个OidcLogoutAuthenticationConverter。 -
AuthenticationManager— 由OidcLogoutAuthenticationProvider组成的AuthenticationManager。 -
AuthenticationSuccessHandler— 一个OidcLogoutAuthenticationSuccessHandler。 -
AuthenticationFailureHandler— 一个内部实现,它使用与OAuth2AuthenticationException关联的OAuth2Error并返回OAuth2Error响应。
OidcLogoutAuthenticationProvider 使用 SessionRegistry 查找与请求注销的终端用户关联的 SessionInformation 实例。 |
OidcClientInitiatedLogoutSuccessHandler 是 Spring Security 的 OAuth2 客户端支持中用于配置 OpenID Connect 1.0 RP 发起的注销 的相应配置。 |
自定义注销请求验证
OidcLogoutAuthenticationValidator 是用于验证特定 OpenID Connect RP 发起的注销请求参数的默认验证器。默认实现验证 post_logout_redirect_uri 参数。如果验证失败,将抛出 OAuth2AuthenticationException。
OidcLogoutAuthenticationProvider 通过向 setAuthenticationValidator() 提供类型为 Consumer<OidcLogoutAuthenticationContext> 的自定义身份验证验证器,提供了覆盖默认注销请求验证的能力。
OidcLogoutAuthenticationContext 包含 OidcLogoutAuthenticationToken,其中包含注销请求参数。 |
如果验证失败,身份验证验证器 必须 抛出 OAuth2AuthenticationException。 |
以下示例展示了如何使用自定义身份验证验证器配置 OidcLogoutAuthenticationProvider
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (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 用户信息端点
OidcUserInfoEndpointConfigurer 提供了自定义 OpenID Connect 1.0 用户信息端点 的能力。它定义了扩展点,允许您自定义 用户信息请求 的预处理、主处理和后处理逻辑。
OidcUserInfoEndpointConfigurer 提供了以下配置选项
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (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 (预处理器),用于尝试将 用户信息请求 从 HttpServletRequest 提取到 OidcUserInfoAuthenticationToken 实例。 |
| 2 | userInfoRequestConverters():设置 Consumer,提供对默认和(可选)添加的 AuthenticationConverter 列表的访问,允许添加、删除或自定义特定的 AuthenticationConverter。 |
| 3 | authenticationProvider():添加一个 AuthenticationProvider (主处理器),用于验证 OidcUserInfoAuthenticationToken。 |
| 4 | authenticationProviders():设置 Consumer,提供对默认和(可选)添加的 AuthenticationProvider 列表的访问,允许添加、删除或自定义特定的 AuthenticationProvider。 |
| 5 | userInfoResponseHandler():AuthenticationSuccessHandler (后处理器),用于处理“已认证”的 OidcUserInfoAuthenticationToken 并返回 用户信息响应。 |
| 6 | errorResponseHandler():AuthenticationFailureHandler (后处理器),用于处理 OAuth2AuthenticationException 并返回 用户信息错误响应。 |
| 7 | userInfoMapper():用于从 OidcUserInfoAuthenticationContext 中提取声明到 OidcUserInfo 实例的 Function。 |
OidcUserInfoEndpointConfigurer 配置 OidcUserInfoEndpointFilter 并将其注册到 OAuth2 授权服务器 SecurityFilterChain @Bean。OidcUserInfoEndpointFilter 是处理 用户信息请求 并返回 OidcUserInfo 响应 的 Filter。
OidcUserInfoEndpointFilter 配置了以下默认值
-
AuthenticationConverter— 一个内部实现,用于从SecurityContext获取Authentication并使用 principal 创建OidcUserInfoAuthenticationToken。 -
AuthenticationManager— 由OidcUserInfoAuthenticationProvider组成的AuthenticationManager,该提供者关联一个userInfoMapper的内部实现,它根据授权期间请求的 范围 从 ID Token 中提取 标准声明。 -
AuthenticationSuccessHandler— 一个内部实现,用于处理“已认证”的OidcUserInfoAuthenticationToken并返回OidcUserInfo响应。 -
AuthenticationFailureHandler— 一个内部实现,它使用与OAuth2AuthenticationException关联的OAuth2Error并返回OAuth2Error响应。
您可以通过提供一个 OAuth2TokenCustomizer<JwtEncodingContext> @Bean 来自定义 ID Token。 |
OpenID Connect 1.0 用户信息端点是一个 OAuth2 受保护资源,要求 在 用户信息请求 中以持有者令牌的形式发送访问令牌。
OAuth2 资源服务器支持是自动配置的,但是,OpenID Connect 1.0 用户信息端点 需要 一个 JwtDecoder @Bean。 |
| 指南 操作指南:自定义 OpenID Connect 1.0 用户信息响应 包含自定义用户信息端点的示例。 |
OpenID Connect 1.0 客户端注册端点
OidcClientRegistrationEndpointConfigurer 提供了自定义 OpenID Connect 1.0 客户端注册端点 的能力。它定义了扩展点,允许您自定义 客户端注册请求 或 客户端读取请求 的预处理、主处理和后处理逻辑。
OidcClientRegistrationEndpointConfigurer 提供了以下配置选项
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (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 (预处理器),用于尝试将 客户端注册请求 或 客户端读取请求 从 HttpServletRequest 提取到 OidcClientRegistrationAuthenticationToken 实例。 |
| 2 | clientRegistrationRequestConverters():设置 Consumer,提供对默认和(可选)添加的 AuthenticationConverter 列表的访问,允许添加、删除或自定义特定的 AuthenticationConverter。 |
| 3 | authenticationProvider():添加一个 AuthenticationProvider (主处理器),用于验证 OidcClientRegistrationAuthenticationToken。 |
| 4 | authenticationProviders():设置 Consumer,提供对默认和(可选)添加的 AuthenticationProvider 列表的访问,允许添加、删除或自定义特定的 AuthenticationProvider。 |
| 5 | clientRegistrationResponseHandler():AuthenticationSuccessHandler (后处理器),用于处理“已认证”的 OidcClientRegistrationAuthenticationToken 并返回 客户端注册响应 或 客户端读取响应。 |
| 6 | errorResponseHandler():AuthenticationFailureHandler (后处理器),用于处理 OAuth2AuthenticationException 并返回 客户端注册错误响应 或 客户端读取错误响应。 |
| OpenID Connect 1.0 客户端注册端点默认禁用,因为许多部署不需要动态客户端注册。 |
OidcClientRegistrationEndpointConfigurer 配置 OidcClientRegistrationEndpointFilter 并将其注册到 OAuth2 授权服务器 SecurityFilterChain @Bean。OidcClientRegistrationEndpointFilter 是处理 客户端注册请求 并返回 OidcClientRegistration 响应 的 Filter。
OidcClientRegistrationEndpointFilter 还处理 客户端读取请求 并返回 OidcClientRegistration 响应。 |
OidcClientRegistrationEndpointFilter 配置了以下默认值
-
AuthenticationConverter— 一个OidcClientRegistrationAuthenticationConverter。 -
AuthenticationManager— 由OidcClientRegistrationAuthenticationProvider和OidcClientConfigurationAuthenticationProvider组成的AuthenticationManager。 -
AuthenticationSuccessHandler— 一个内部实现,用于处理“已认证”的OidcClientRegistrationAuthenticationToken并返回OidcClientRegistration响应。 -
AuthenticationFailureHandler— 一个内部实现,它使用与OAuth2AuthenticationException关联的OAuth2Error并返回OAuth2Error响应。
OpenID Connect 1.0 客户端注册端点是一个 OAuth2 受保护资源,要求 在客户端注册(或客户端读取)请求中以持有者令牌的形式发送访问令牌。
OAuth2 资源服务器支持是自动配置的,但是,OpenID Connect 1.0 客户端注册端点 需要 一个 JwtDecoder @Bean。 |
客户端注册请求中的访问令牌 需要 OAuth2 范围 client.create。 |
客户端读取请求中的访问令牌 需要 OAuth2 范围 client.read。 |