Configuration Model

Default configuration

OAuth2AuthorizationServerConfiguration 是一个 @Configuration,它为 OAuth2 授权服务器提供最小的默认配置。

OAuth2AuthorizationServerConfiguration 使用 OAuth2AuthorizationServerConfigurer 来应用默认配置,并注册一个 SecurityFilterChain @Bean,其中包括支持一个 OAuth2 授权服务器的所有基础架构组件。

OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(HttpSecurity) 是一个便捷 (static) 实用方法,用于将默认 OAuth2 安全配置应用于 HttpSecurity

OAuth2 授权服务器 SecurityFilterChain @Bean 使用以下默认协议端点配置:

如果一个 JWKSource<SecurityContext> @Bean 已注册,则 JWK 集端点 only 已配置。

以下示例演示如何使用 OAuth2AuthorizationServerConfiguration 应用最小的默认配置:

@Configuration
@Import(OAuth2AuthorizationServerConfiguration.class)
public class AuthorizationServerConfig {

	@Bean
	public RegisteredClientRepository registeredClientRepository() {
		List<RegisteredClient> registrations = ...
		return new InMemoryRegisteredClientRepository(registrations);
	}

	@Bean
	public JWKSource<SecurityContext> jwkSource() {
		RSAKey rsaKey = ...
		JWKSet jwkSet = new JWKSet(rsaKey);
		return (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
	}

}

authorization_code grant 要求资源所有者已通过身份验证。因此,除了默认的 OAuth2 安全配置之外,还需要配置一个用户身份验证机制 must

在默认配置中禁用了 OpenID Connect 1.0。以下示例展示了如何通过初始化`OidcConfigurer`来启用OpenID Connect 1.0:

@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
	OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);

	http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
		.oidc(Customizer.withDefaults());	// Initialize `OidcConfigurer`

	return http.build();
}

除了默认协议端点外,OAuth2 授权服务器 SecurityFilterChain @Bean 还使用以下 OpenID Connect 1.0 协议端点配置:

默认情况下,OpenID Connect 1.0 Client Registration endpoint 被禁用,因为许多部署不需要动态客户端注册。

OAuth2AuthorizationServerConfiguration.jwtDecoder(JWKSource<SecurityContext>)`是一个便利(`static)工具方法,可用于注册一个`JwtDecoder``@Bean`,也就是*REQUIRED*的OpenID Connect 1.0 UserInfo endpointOpenID Connect 1.0 Client Registration endpoint

以下示例演示如何注册一个 JwtDecoder @Bean

@Bean
public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
	return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
}

OAuth2AuthorizationServerConfiguration 的主要目的是提供一种方便的方法来应用 OAuth2 授权服务器的最小的默认配置。不过,在大多数情况下,需要自定义配置。

Customizing the configuration

OAuth2AuthorizationServerConfigurer 提供完全自定义针对 OAuth2 授权服务器的安全配置的能力。它允许你指定要使用的核心组件——例如 RegisteredClientRepositoryOAuth2AuthorizationServiceOAuth2TokenGenerator等等。此外,它允许你自定义针对协议端点的请求处理逻辑——例如 authorization endpointdevice authorization endpointdevice verification endpointtoken endpointtoken introspection endpoint等等。

OAuth2AuthorizationServerConfigurer 提供以下配置选项:

@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
		new OAuth2AuthorizationServerConfigurer();
	http.apply(authorizationServerConfigurer);

	authorizationServerConfigurer
		.registeredClientRepository(registeredClientRepository) 1
		.authorizationService(authorizationService) 2
		.authorizationConsentService(authorizationConsentService)   3
		.authorizationServerSettings(authorizationServerSettings) 4
		.tokenGenerator(tokenGenerator) 5
		.clientAuthentication(clientAuthentication -> { })  6
		.authorizationEndpoint(authorizationEndpoint -> { })    7
		.deviceAuthorizationEndpoint(deviceAuthorizationEndpoint -> { })    8
		.deviceVerificationEndpoint(deviceVerificationEndpoint -> { })  9
		.tokenEndpoint(tokenEndpoint -> { })    10
		.tokenIntrospectionEndpoint(tokenIntrospectionEndpoint -> { })  11
		.tokenRevocationEndpoint(tokenRevocationEndpoint -> { })    12
		.authorizationServerMetadataEndpoint(authorizationServerMetadataEndpoint -> { })    13
		.oidc(oidc -> oidc
			.providerConfigurationEndpoint(providerConfigurationEndpoint -> { })    14
			.logoutEndpoint(logoutEndpoint -> { })  15
			.userInfoEndpoint(userInfoEndpoint -> { })  16
			.clientRegistrationEndpoint(clientRegistrationEndpoint -> { })  17
		);

	return http.build();
}
<1>  `registeredClientRepository()`:管理新旧客户的 xref:core-model-components.adoc#registered-client-repository[`RegisteredClientRepository`] (*REQUIRED*)。
<1>  `authorizationService()`:管理新旧授权的 xref:core-model-components.adoc#oauth2-authorization-service[`OAuth2AuthorizationService`]。
<1>  `authorizationConsentService()`:管理新旧授权同意的 xref:core-model-components.adoc#oauth2-authorization-consent-service[`OAuth2AuthorizationConsentService`]。
<1>  `authorizationServerSettings()`:用于自定义 OAuth2 授权服务器的配置设置的 xref:configuration-model.adoc#configuring-authorization-server-settings[`AuthorizationServerSettings`] (*REQUIRED*)。
<1>  `tokenGenerator()`:用于生成由 OAuth2 授权服务器支持的令牌的 xref:core-model-components.adoc#oauth2-token-generator[`OAuth2TokenGenerator`]。
<1>  `clientAuthentication()`:xref:configuration-model.adoc#configuring-client-authentication[OAuth2 Client Authentication] 的配置器。
<1>  `authorizationEndpoint()`:xref:protocol-endpoints.adoc#oauth2-authorization-endpoint[OAuth2 Authorization endpoint] 的配置器。
<1>  `deviceAuthorizationEndpoint()`:xref:protocol-endpoints.adoc#oauth2-device-authorization-endpoint[OAuth2 Device Authorization endpoint] 的配置器。
<1>  `deviceVerificationEndpoint()`:xref:protocol-endpoints.adoc#oauth2-device-verification-endpoint[OAuth2 Device Verification endpoint] 的配置器。
<1>  `tokenEndpoint()`:xref:protocol-endpoints.adoc#oauth2-token-endpoint[OAuth2 Token endpoint] 的配置器。
<1>  `tokenIntrospectionEndpoint()`:xref:protocol-endpoints.adoc#oauth2-token-introspection-endpoint[OAuth2 Token Introspection endpoint] 的配置器。
<1>  `tokenRevocationEndpoint()`:xref:protocol-endpoints.adoc#oauth2-token-revocation-endpoint[OAuth2 Token Revocation endpoint] 的配置器。
<1>  `authorizationServerMetadataEndpoint()`:xref:protocol-endpoints.adoc#oauth2-authorization-server-metadata-endpoint[OAuth2 Authorization Server Metadata endpoint] 的配置器。
<1>  `providerConfigurationEndpoint()`:xref:protocol-endpoints.adoc#oidc-provider-configuration-endpoint[OpenID Connect 1.0 Provider Configuration endpoint] 的配置器。
<1>  `logoutEndpoint()`:xref:protocol-endpoints.adoc#oidc-logout-endpoint[OpenID Connect 1.0 Logout endpoint] 的配置器。
<1>  `userInfoEndpoint()`:xref:protocol-endpoints.adoc#oidc-user-info-endpoint[OpenID Connect 1.0 UserInfo endpoint] 的配置器。
<1>  `clientRegistrationEndpoint()`:xref:protocol-endpoints.adoc#oidc-client-registration-endpoint[OpenID Connect 1.0 Client Registration endpoint] 的配置器。

Configuring Authorization Server Settings

AuthorizationServerSettings`包含OAuth2授权服务器的配置设置。它指定协议端点的`URI,以及 issuer identifier.针对协议端点的默认`URI`如下所示:

public final class AuthorizationServerSettings extends AbstractSettings {

	...

	public static Builder builder() {
		return new Builder()
			.authorizationEndpoint("/oauth2/authorize")
			.deviceAuthorizationEndpoint("/oauth2/device_authorization")
			.deviceVerificationEndpoint("/oauth2/device_verification")
			.tokenEndpoint("/oauth2/token")
			.tokenIntrospectionEndpoint("/oauth2/introspect")
			.tokenRevocationEndpoint("/oauth2/revoke")
			.jwkSetEndpoint("/oauth2/jwks")
			.oidcLogoutEndpoint("/connect/logout")
			.oidcUserInfoEndpoint("/userinfo")
			.oidcClientRegistrationEndpoint("/connect/register");
	}

	...

}

AuthorizationServerSettings 是一个 REQUIRED 组件。

如果尚未提供,@Import(OAuth2AuthorizationServerConfiguration.class)将自动注册一个`AuthorizationServerSettings``@Bean`。

以下示例演示如何自定义配置设置并注册一个 AuthorizationServerSettings @Bean

@Bean
public AuthorizationServerSettings authorizationServerSettings() {
	return AuthorizationServerSettings.builder()
		.issuer("https://example.com")
		.authorizationEndpoint("/oauth2/v1/authorize")
		.deviceAuthorizationEndpoint("/oauth2/v1/device_authorization")
		.deviceVerificationEndpoint("/oauth2/v1/device_verification")
		.tokenEndpoint("/oauth2/v1/token")
		.tokenIntrospectionEndpoint("/oauth2/v1/introspect")
		.tokenRevocationEndpoint("/oauth2/v1/revoke")
		.jwkSetEndpoint("/oauth2/v1/jwks")
		.oidcLogoutEndpoint("/connect/v1/logout")
		.oidcUserInfoEndpoint("/connect/v1/userinfo")
		.oidcClientRegistrationEndpoint("/connect/v1/register")
		.build();
}

AuthorizationServerContext 是一个上下文对象,它保存授权服务器运行时环境的信息。可通过它访问 AuthorizationServerSettings 和“当前”颁发者标识符。

如果没有在 AuthorizationServerSettings.builder().issuer(String) 中配置发行者标识符,它将从当前请求中解析。

AuthorizationServerContext 可通过 AuthorizationServerContextHolder 访问,它将 AuthorizationServerContext 与当前请求线程关联,方式是使用 ThreadLocal

Configuring Client Authentication

`OAuth2ClientAuthenticationConfigurer`提供了自定义 OAuth2 client authentication的能力。它定义了让你能够自定义针对客户端认证请求进行预处理、主处理和后处理逻辑的扩展点。

OAuth2ClientAuthenticationConfigurer 提供以下配置选项:

@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
		new OAuth2AuthorizationServerConfigurer();
	http.apply(authorizationServerConfigurer);

	authorizationServerConfigurer
		.clientAuthentication(clientAuthentication ->
			clientAuthentication
				.authenticationConverter(authenticationConverter)   1
				.authenticationConverters(authenticationConvertersConsumer) 2
				.authenticationProvider(authenticationProvider) 3
				.authenticationProviders(authenticationProvidersConsumer)   4
				.authenticationSuccessHandler(authenticationSuccessHandler) 5
				.errorResponseHandler(errorResponseHandler) 6
		);

	return http.build();
}
<1>  `authenticationConverter()`: 向 `OAuth2ClientAuthenticationToken` 的实例添加在尝试从 `HttpServletRequest` 提取客户端凭据时使用的 `AuthenticationConverter` (_pre-processor_)。
<1>  `authenticationConverters()`: 设置的 `Consumer` 提供对默认和(可选)添加的 `AuthenticationConverter&amp;#8217;s allowing the ability to add, remove, or customize a specific `AuthenticationConverter` 的访问权限。
<1>  `authenticationProvider()`: 添加用于对 `OAuth2ClientAuthenticationToken` 进行身份验证的 `AuthenticationProvider` (_main processor_)。
<1>  `authenticationProviders()`:设置一个 `Consumer`,提供对默认和(可选)添加的 `AuthenticationProvider&amp;#8217;s allowing the ability to add, remove, or customize a specific `AuthenticationProvider` 的 `List` 的访问。
<1>  `authenticationSuccessHandler()`:用于处理成功的客户端身份验证并将 `OAuth2ClientAuthenticationToken` 与 `SecurityContext` 相关联的 `AuthenticationSuccessHandler` (_post-processor_)。
<1>  `errorResponseHandler()`:用于处理失败的客户端身份验证并返回 link:https://datatracker.ietf.org/doc/html/rfc6749#section-5.2[`OAuth2Error` 响应的 `AuthenticationFailureHandler` (_post-processor_)。

OAuth2ClientAuthenticationConfigurer 配置 OAuth2ClientAuthenticationFilter 并将其注册到 OAuth2 授权服务器 SecurityFilterChain @BeanOAuth2ClientAuthenticationFilter 是处理客户端身份验证请求的 Filter

在默认情况下,客户端验证对于 OAuth2 Token endpointOAuth2 Token Introspection endpointOAuth2 Token Revocation endpoint 是必需的。所支持的客户端验证方法是 client_secret_basicclient_secret_postprivate_key_jwtclient_secret_jwt`和 `none (公共客户端)。

OAuth2ClientAuthenticationFilter 使用以下默认值配置:

  • AuthenticationConverter — 由 JwtClientAssertionAuthenticationConverterClientSecretBasicAuthenticationConverterClientSecretPostAuthenticationConverterPublicClientAuthenticationConverter 组成的一个 DelegatingAuthenticationConverter

  • AuthenticationManager — 由 JwtClientAssertionAuthenticationProviderClientSecretAuthenticationProviderPublicClientAuthenticationProvider 组成的一个 AuthenticationManager

  • AuthenticationSuccessHandler — 将 “authenticated” OAuth2ClientAuthenticationToken (当前 Authentication) 与 SecurityContext 关联的内部实现。

  • AuthenticationFailureHandler — 使用与 OAuth2AuthenticationException 关联的 OAuth2Error 来返回 OAuth2 错误响应的内部实现。

Customizing Jwt Client Assertion Validation

JwtClientAssertionDecoderFactory.DEFAULT_JWT_VALIDATOR_FACTORY 是为指定 RegisteredClient 提供 OAuth2TokenValidator<Jwt> 的默认工厂,用于验证 Jwt 客户端声明的 isssubaudexpnbf 声明。

JwtClientAssertionDecoderFactory 提供了覆盖默认 Jwt 客户端声明验证的功能,方法是向 setJwtValidatorFactory() 提供一个类型为 Function<RegisteredClient, OAuth2TokenValidator<Jwt>> 的自定义工厂。

JwtClientAssertionDecoderFactoryJwtClientAssertionAuthenticationProvider 使用的默认 JwtDecoderFactory,它为指定的 RegisteredClient 提供 JwtDecoder,用于在 OAuth2 客户端身份验证期间验证 Jwt Bearer 令牌。

自定义 JwtClientAssertionDecoderFactory 的常见用例是在 Jwt 客户端声明中验证其他声明。

以下示例展示了如何使用一个自定义的 JwtClientAssertionDecoderFactory 来配置 JwtClientAssertionAuthenticationProvider,该工厂会在 Jwt 客户端声明中验证其他声明:

@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
	OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
		new OAuth2AuthorizationServerConfigurer();
	http.apply(authorizationServerConfigurer);

	authorizationServerConfigurer
		.clientAuthentication(clientAuthentication ->
			clientAuthentication
				.authenticationProviders(configureJwtClientAssertionValidator())
		);

	return http.build();
}

private Consumer<List<AuthenticationProvider>> configureJwtClientAssertionValidator() {
	return (authenticationProviders) ->
		authenticationProviders.forEach((authenticationProvider) -> {
			if (authenticationProvider instanceof JwtClientAssertionAuthenticationProvider) {
				// Customize JwtClientAssertionDecoderFactory
				JwtClientAssertionDecoderFactory jwtDecoderFactory = new JwtClientAssertionDecoderFactory();
				Function<RegisteredClient, OAuth2TokenValidator<Jwt>> jwtValidatorFactory = (registeredClient) ->
					new DelegatingOAuth2TokenValidator<>(
						// Use default validators
						JwtClientAssertionDecoderFactory.DEFAULT_JWT_VALIDATOR_FACTORY.apply(registeredClient),
						// Add custom validator
						new JwtClaimValidator<>("claim", "value"::equals));
				jwtDecoderFactory.setJwtValidatorFactory(jwtValidatorFactory);

				((JwtClientAssertionAuthenticationProvider) authenticationProvider)
					.setJwtDecoderFactory(jwtDecoderFactory);
			}
		});
}