协议端点

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 提取到 OAuth2AuthorizationCodeRequestAuthenticationTokenOAuth2AuthorizationConsentAuthenticationToken 实例。
2 authorizationRequestConverters():设置 Consumer,提供对默认和(可选)添加的 AuthenticationConverter 列表的访问,允许添加、删除或自定义特定的 AuthenticationConverter
3 authenticationProvider():添加一个 AuthenticationProvider (主处理器),用于验证 OAuth2AuthorizationCodeRequestAuthenticationTokenOAuth2AuthorizationConsentAuthenticationToken
4 authenticationProviders():设置 Consumer,提供对默认和(可选)添加的 AuthenticationProvider 列表的访问,允许添加、删除或自定义特定的 AuthenticationProvider
5 authorizationResponseHandler()AuthenticationSuccessHandler (后处理器),用于处理“已认证”的 OAuth2AuthorizationCodeRequestAuthenticationToken 并返回 OAuth2AuthorizationResponse
6 errorResponseHandler()AuthenticationFailureHandler (后处理器),用于处理 OAuth2AuthorizationCodeRequestAuthenticationException 并返回 OAuth2Error 响应
7 consentPage():自定义同意页面的 URI,如果授权请求流程中需要同意,则重定向资源所有者到该页面。

OAuth2AuthorizationEndpointConfigurer 配置 OAuth2AuthorizationEndpointFilter 并将其注册到 OAuth2 授权服务器 SecurityFilterChain @BeanOAuth2AuthorizationEndpointFilter 是处理 OAuth2 授权请求(和同意)的 Filter

OAuth2AuthorizationEndpointFilter 配置了以下默认值

  • AuthenticationConverter — 由 OAuth2AuthorizationCodeRequestAuthenticationConverterOAuth2AuthorizationConsentAuthenticationConverter 组成的 DelegatingAuthenticationConverter

  • AuthenticationManager — 由 OAuth2AuthorizationCodeRequestAuthenticationProviderOAuth2AuthorizationConsentAuthenticationProvider 组成的 AuthenticationManager

  • AuthenticationSuccessHandler — 一个内部实现,用于处理“已认证”的 OAuth2AuthorizationCodeRequestAuthenticationToken 并返回 OAuth2AuthorizationResponse

  • AuthenticationFailureHandler — 一个内部实现,它使用与 OAuth2AuthorizationCodeRequestAuthenticationException 关联的 OAuth2Error 并返回 OAuth2Error 响应。

自定义授权请求验证

OAuth2AuthorizationCodeRequestAuthenticationValidator 是用于验证授权码授权中特定 OAuth2 授权请求参数的默认验证器。默认实现验证 redirect_uriscope 参数。如果验证失败,将抛出 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 @BeanOAuth2PushedAuthorizationRequestEndpointFilter 是处理 OAuth2 推送授权请求的 Filter

OAuth2PushedAuthorizationRequestEndpointFilter 配置了以下默认值

  • AuthenticationConverter — 由 OAuth2AuthorizationCodeRequestAuthenticationConverter 组成的 DelegatingAuthenticationConverter

  • AuthenticationManager — 由 OAuth2PushedAuthorizationRequestAuthenticationProvider 组成的 AuthenticationManager

  • AuthenticationSuccessHandler — 一个内部实现,用于处理“已认证”的 OAuth2PushedAuthorizationRequestAuthenticationToken 并返回 OAuth2 推送授权响应。

  • AuthenticationFailureHandler — 一个 OAuth2ErrorAuthenticationFailureHandler

自定义推送授权请求验证

OAuth2AuthorizationCodeRequestAuthenticationValidator 是用于验证授权码授权中特定 OAuth2 推送授权请求参数的默认验证器。默认实现验证 redirect_uriscope 参数。如果验证失败,将抛出 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 @BeanOAuth2DeviceAuthorizationEndpointFilter 是处理 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 提取到 OAuth2DeviceVerificationAuthenticationTokenOAuth2DeviceAuthorizationConsentAuthenticationToken 实例。
2 deviceVerificationRequestConverters():设置 Consumer,提供对默认和(可选)添加的 AuthenticationConverter 列表的访问,允许添加、删除或自定义特定的 AuthenticationConverter
3 authenticationProvider():添加一个 AuthenticationProvider (主处理器),用于验证 OAuth2DeviceVerificationAuthenticationTokenOAuth2DeviceAuthorizationConsentAuthenticationToken
4 authenticationProviders():设置 Consumer,提供对默认和(可选)添加的 AuthenticationProvider 列表的访问,允许添加、删除或自定义特定的 AuthenticationProvider
5 deviceVerificationResponseHandler()AuthenticationSuccessHandler (后处理器),用于处理“已认证”的 OAuth2DeviceVerificationAuthenticationToken 并引导资源所有者返回其设备。
6 errorResponseHandler()AuthenticationFailureHandler (后处理器),用于处理 OAuth2AuthenticationException 并返回错误响应。
7 consentPage():自定义同意页面的 URI,如果设备验证请求流程中需要同意,则重定向资源所有者到该页面。

OAuth2DeviceVerificationEndpointConfigurer 配置 OAuth2DeviceVerificationEndpointFilter 并将其注册到 OAuth2 授权服务器 SecurityFilterChain @BeanOAuth2DeviceVerificationEndpointFilter 是处理 OAuth2 设备验证请求(和同意)的 Filter

OAuth2DeviceVerificationEndpointFilter 配置了以下默认值

  • AuthenticationConverter — 由 OAuth2DeviceVerificationAuthenticationConverterOAuth2DeviceAuthorizationConsentAuthenticationConverter 组成的 DelegatingAuthenticationConverter

  • AuthenticationManager — 由 OAuth2DeviceVerificationAuthenticationProviderOAuth2DeviceAuthorizationConsentAuthenticationProvider 组成的 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 @BeanOAuth2TokenEndpointFilter 是处理 OAuth2 访问令牌请求的 Filter

支持的 授权类型authorization_coderefresh_tokenclient_credentialsurn:ietf:params:oauth:grant-type:device_codeurn:ietf:params:oauth:grant-type:token_exchange

OAuth2TokenEndpointFilter 配置了以下默认值

  • AuthenticationConverter — 由 OAuth2AuthorizationCodeAuthenticationConverterOAuth2RefreshTokenAuthenticationConverterOAuth2ClientCredentialsAuthenticationConverterOAuth2DeviceCodeAuthenticationConverterOAuth2TokenExchangeAuthenticationConverter 组成的 DelegatingAuthenticationConverter

  • AuthenticationManager — 由 OAuth2AuthorizationCodeAuthenticationProviderOAuth2RefreshTokenAuthenticationProviderOAuth2ClientCredentialsAuthenticationProviderOAuth2DeviceCodeAuthenticationProviderOAuth2TokenExchangeAuthenticationProvider 组成的 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_coderefresh_tokenclient_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 @BeanOAuth2TokenIntrospectionEndpointFilter 是处理 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 @BeanOAuth2TokenRevocationEndpointFilter 是处理 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 @BeanOAuth2AuthorizationServerMetadataEndpointFilter 是返回 OAuth2AuthorizationServerMetadata 响应Filter

JWK 设置端点

OAuth2AuthorizationServerConfigurer 支持 JWK 设置端点

OAuth2AuthorizationServerConfigurer 配置 NimbusJwkSetEndpointFilter 并将其注册到 OAuth2 授权服务器 SecurityFilterChain @BeanNimbusJwkSetEndpointFilter 是返回 JWK 集Filter

JWK Set 端点仅在注册了 JWKSource<SecurityContext> @Bean 时才配置。

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 @BeanOidcProviderConfigurationEndpointFilter 是返回 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 @BeanOidcLogoutEndpointFilter 是处理 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 @BeanOidcUserInfoEndpointFilter 是处理 用户信息请求 并返回 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 @BeanOidcClientRegistrationEndpointFilter 是处理 客户端注册请求 并返回 OidcClientRegistration 响应Filter

OidcClientRegistrationEndpointFilter 还处理 客户端读取请求 并返回 OidcClientRegistration 响应

OidcClientRegistrationEndpointFilter 配置了以下默认值

  • AuthenticationConverter — 一个 OidcClientRegistrationAuthenticationConverter

  • AuthenticationManager — 由 OidcClientRegistrationAuthenticationProviderOidcClientConfigurationAuthenticationProvider 组成的 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
© . This site is unofficial and not affiliated with VMware.