此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Authorization Server 1.4.0spring-doc.cn

配置模型

默认配置

OAuth2AuthorizationServerConfiguration是为 OAuth2 授权服务器提供最低默认配置的 a。@Configurationspring-doc.cn

OAuth2AuthorizationServerConfiguration使用 OAuth2AuthorizationServerConfigurer 应用默认配置,并注册一个由支持 OAuth2 授权服务器的所有基础设施组件组成的组件。SecurityFilterChain@Beanspring-doc.cn

OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(HttpSecurity)是一种便捷的 () 实用程序方法,它将默认的 OAuth2 安全配置应用于 。staticHttpSecurity

OAuth2 授权服务器配置了以下默认协议端点:SecurityFilterChain@Beanspring-doc.cn

仅当注册了 a 时,才会配置 JWK Set 端点。JWKSource<SecurityContext>@Bean

以下示例显示如何使用 应用最小默认配置:OAuth2AuthorizationServerConfigurationspring-doc.cn

@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授权要求资源所有者进行身份验证。因此,除了默认的 OAuth2 安全配置之外,还必须配置用户身份验证机制。

OpenID Connect 1.0 在默认配置中处于禁用状态。以下示例显示了如何通过初始化 OpenID Connect 1.0 来启用:OidcConfigurerspring-doc.cn

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

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

	return http.build();
}

除了默认协议端点之外,OAuth2 授权服务器还配置了以下 OpenID Connect 1.0 协议端点:SecurityFilterChain@Beanspring-doc.cn

默认情况下,OpenID Connect 1.0 客户端注册终端节点处于禁用状态,因为许多部署不需要动态客户端注册。
OAuth2AuthorizationServerConfiguration.jwtDecoder(JWKSource<SecurityContext>)是一种方便的 () 实用程序方法,可用于注册 ,对于 OpenID Connect 1.0 UserInfo 端点OpenID Connect 1.0 客户端注册端点是必需的。staticJwtDecoder@Bean

以下示例说明如何注册 :JwtDecoder@Beanspring-doc.cn

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

的主要目的是提供一种方便的方法来为 OAuth2 授权服务器应用最低默认配置。但是,在大多数情况下,需要自定义配置。OAuth2AuthorizationServerConfigurationspring-doc.cn

自定义配置

OAuth2AuthorizationServerConfigurer提供完全自定义 OAuth2 授权服务器安全配置的能力。 它允许您指定要使用的核心组件 - 例如,RegisteredClientRepositoryOAuth2AuthorizationServiceOAuth2TokenGenerator 等。 此外,它还允许您自定义协议终端节点的请求处理逻辑,例如,授权终端节点设备授权终端节点设备验证终端节点令牌终端节点令牌自检终端节点等。spring-doc.cn

OAuth2AuthorizationServerConfigurer提供以下配置选项:spring-doc.cn

@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():用于管理新客户端和现有客户端的 RegisteredClientRepositoryREQUIRED)。
2 authorizationService():用于管理新授权和现有授权的 OAuth2AuthorizationService
3 authorizationConsentService()OAuth2AuthorizationConsentService,用于管理新的和现有的授权同意。
4 authorizationServerSettings():用于自定义 OAuth2 授权服务器的配置设置的 AuthorizationServerSettingsREQUIRED)。
5 tokenGenerator()OAuth2TokenGenerator,用于生成 OAuth2 授权服务器支持的令牌。
6 clientAuthentication()OAuth2 客户端身份验证的配置器。
7 authorizationEndpoint()OAuth2 授权端点的配置器。
8 deviceAuthorizationEndpoint()OAuth2 设备授权端点的配置器。
9 deviceVerificationEndpoint()OAuth2 Device Verification 端点的配置器。
10 tokenEndpoint()OAuth2 令牌端点的配置器。
11 tokenIntrospectionEndpoint()OAuth2 令牌自省端点的配置器。
12 tokenRevocationEndpoint()OAuth2 令牌吊销端点的配置器。
13 authorizationServerMetadataEndpoint()OAuth2 授权服务器元数据端点的配置器。
14 providerConfigurationEndpoint()OpenID Connect 1.0 提供程序配置终端节点的配置器。
15 logoutEndpoint()OpenID Connect 1.0 注销端点的配置器。
16 userInfoEndpoint()OpenID Connect 1.0 UserInfo 端点的配置器。
17 clientRegistrationEndpoint()OpenID Connect 1.0 客户端注册终端节点的配置器。

配置 Authorization Server 设置

AuthorizationServerSettings包含 OAuth2 授权服务器的配置设置。 它指定协议端点以及颁发者标识符。 协议终端节点的默认值如下:URIURIspring-doc.cn

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");
	}

	...

}
AuthorizationServerSettingsREQUIRED 组件。
@Import(OAuth2AuthorizationServerConfiguration.class) 会自动注册一个 (如果尚未提供)。AuthorizationServerSettings@Bean

以下示例显示如何自定义配置设置并注册 :AuthorizationServerSettings@Beanspring-doc.cn

@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();
}

它是一个上下文对象,用于保存 Authorization Server 运行时环境的信息。 它提供对 和 “current” issuer 标识符的访问。AuthorizationServerContextAuthorizationServerSettingsspring-doc.cn

如果未在 中配置颁发者标识符,则会从当前请求中解析该标识符。AuthorizationServerSettings.builder().issuer(String)
可通过 访问,后者使用 将其与当前请求线程相关联。AuthorizationServerContextAuthorizationServerContextHolderThreadLocal

配置客户端身份验证

OAuth2ClientAuthenticationConfigurer提供自定义 OAuth2 客户端身份验证的功能。 它定义了扩展点,允许您自定义客户端身份验证请求的预处理、主处理和后处理逻辑。spring-doc.cn

OAuth2ClientAuthenticationConfigurer提供以下配置选项:spring-doc.cn

@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():添加尝试从 中提取客户端凭据到 实例时使用的(预处理器)。AuthenticationConverterHttpServletRequestOAuth2ClientAuthenticationToken
2 authenticationConverters():设置对 default 和(可选)added 的 提供访问权限,以允许添加、删除或自定义特定 .ConsumerListAuthenticationConverterAuthenticationConverter
3 authenticationProvider():添加一个(主处理器)用于验证 .AuthenticationProviderOAuth2ClientAuthenticationToken
4 authenticationProviders():设置对 default 和(可选)added 的 提供访问权限,以允许添加、删除或自定义特定 .ConsumerListAuthenticationProviderAuthenticationProvider
5 authenticationSuccessHandler():用于处理成功的客户端身份验证并将 关联到 的(后处理器)。AuthenticationSuccessHandlerOAuth2ClientAuthenticationTokenSecurityContext
6 errorResponseHandler():用于处理失败的客户端身份验证并返回 OAuth2Error 响应的(后处理器)。AuthenticationFailureHandler

OAuth2ClientAuthenticationConfigurer配置 并将其注册到 OAuth2 授权服务器 。 是处理客户端身份验证请求的 。OAuth2ClientAuthenticationFilterSecurityFilterChain@BeanOAuth2ClientAuthenticationFilterFilterspring-doc.cn

默认情况下,OAuth2 令牌端点OAuth2 令牌自检端点OAuth2 令牌吊销端点需要客户端身份验证。 支持的客户端身份验证方法包括 、 和 (公共客户端)。client_secret_basicclient_secret_postprivate_key_jwtclient_secret_jwttls_client_authself_signed_tls_client_authnonespring-doc.cn

OAuth2ClientAuthenticationFilter配置了以下默认值:spring-doc.cn

  • AuthenticationConverter— A 由 、 、 、 和 组成。DelegatingAuthenticationConverterJwtClientAssertionAuthenticationConverterX509ClientCertificateAuthenticationConverterClientSecretBasicAuthenticationConverterClientSecretPostAuthenticationConverterPublicClientAuthenticationConverterspring-doc.cn

  • AuthenticationManager— 由 、 、 和 组成的 。AuthenticationManagerJwtClientAssertionAuthenticationProviderX509ClientCertificateAuthenticationProviderClientSecretAuthenticationProviderPublicClientAuthenticationProviderspring-doc.cn

  • AuthenticationSuccessHandler— 将 “authenticated” (当前) 与 关联的内部实现。OAuth2ClientAuthenticationTokenAuthenticationSecurityContextspring-doc.cn

  • AuthenticationFailureHandler— 一种内部实现,它使用与 关联的 来返回 OAuth2 错误响应。OAuth2ErrorOAuth2AuthenticationExceptionspring-doc.cn

自定义 Jwt 客户端断言验证

JwtClientAssertionDecoderFactory.DEFAULT_JWT_VALIDATOR_FACTORY是为指定 提供 的默认工厂,用于验证客户端断言的 、 、 和 声明。OAuth2TokenValidator<Jwt>RegisteredClientisssubaudexpnbfJwtspring-doc.cn

JwtClientAssertionDecoderFactory通过向 提供 类型的自定义工厂来覆盖默认客户端断言验证的功能。JwtFunction<RegisteredClient, OAuth2TokenValidator<Jwt>>setJwtValidatorFactory()spring-doc.cn

JwtClientAssertionDecoderFactory是默认使用的,它为指定提供 ,并用于在 OAuth2 客户端身份验证期间验证 Bearer Token。JwtDecoderFactoryJwtClientAssertionAuthenticationProviderJwtDecoderRegisteredClientJwt

自定义的一个常见用例是验证客户端断言中的其他声明。JwtClientAssertionDecoderFactoryJwtspring-doc.cn

以下示例显示如何使用自定义进行配置,以验证客户端断言中的其他声明:JwtClientAssertionAuthenticationProviderJwtClientAssertionDecoderFactoryJwtspring-doc.cn

@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);
			}
		});
}

自定义 Mutual-TLS 客户端验证

X509ClientCertificateAuthenticationProvider用于验证在 OAuth2 客户端验证期间使用或方法时收到的客户端链。 它还由“证书验证程序”组成,用于在 TLS 握手成功完成后验证客户端的内容。X509CertificateClientAuthenticationMethod.TLS_CLIENT_AUTHClientAuthenticationMethod.SELF_SIGNED_TLS_CLIENT_AUTHX509Certificatespring-doc.cn

PKI 互助 TLS 方法

对于 PKI Mutual-TLS () 方法,证书验证程序的默认实现会根据设置 验证客户端的使用者可分辨名称。ClientAuthenticationMethod.TLS_CLIENT_AUTHX509CertificateRegisteredClient.getClientSettings.getX509CertificateSubjectDN()spring-doc.cn

如果需要验证 client 的另一个属性,例如主题备用名称 (SAN) 条目,以下示例显示如何使用证书验证程序的自定义实施进行配置:X509CertificateX509ClientCertificateAuthenticationProviderspring-doc.cn

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

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

	return http.build();
}

private Consumer<List<AuthenticationProvider>> configureX509ClientCertificateVerifier() {
	return (authenticationProviders) ->
			authenticationProviders.forEach((authenticationProvider) -> {
				if (authenticationProvider instanceof X509ClientCertificateAuthenticationProvider) {
					Consumer<OAuth2ClientAuthenticationContext> certificateVerifier = (clientAuthenticationContext) -> {
						OAuth2ClientAuthenticationToken clientAuthentication = clientAuthenticationContext.getAuthentication();
						RegisteredClient registeredClient = clientAuthenticationContext.getRegisteredClient();
						X509Certificate[] clientCertificateChain = (X509Certificate[]) clientAuthentication.getCredentials();
						X509Certificate clientCertificate = clientCertificateChain[0];

						// TODO Verify Subject Alternative Name (SAN) entry

					};

					((X509ClientCertificateAuthenticationProvider) authenticationProvider)
							.setCertificateVerifier(certificateVerifier);
				}
			});
}

自签名证书互助 TLS 方法

对于自签名证书互惠 TLS () 方法,证书验证程序的默认实现将使用该设置检索客户端的 JSON Web 密钥集,并期望找到与在 TLS 握手期间收到的客户端的匹配项。ClientAuthenticationMethod.SELF_SIGNED_TLS_CLIENT_AUTHRegisteredClient.getClientSettings.getJwkSetUrl()X509Certificatespring-doc.cn

该设置用于通过 JSON Web 密钥 (JWK) 集检索客户端的证书。 证书由证书集中单个 JWK 的参数表示。RegisteredClient.getClientSettings.getJwkSetUrl()x5c

客户端 Certificate-Bound Access Token

在令牌端点使用 Mutual-TLS 客户端身份验证时,授权服务器能够将颁发的访问令牌绑定到客户端的 . 绑定是通过计算客户端的 SHA-256 指纹并将指纹与访问令牌相关联来完成的。 例如,JWT 访问令牌将在顶级(确认方法)声明中包含包含指纹的声明。X509CertificateX509Certificatex5t#S256X509Certificatecnfspring-doc.cn

将访问令牌绑定到客户端的令牌提供了在受保护资源访问期间实施所有权证明机制的能力。 例如,受保护的资源将获取客户端在 Mutual-TLS 身份验证期间使用的指纹,然后验证证书指纹是否与与访问令牌关联的声明匹配。X509CertificateX509Certificatex5t#S256spring-doc.cn

以下示例显示如何为客户端启用证书绑定访问令牌:spring-doc.cn

RegisteredClient mtlsClient = RegisteredClient.withId(UUID.randomUUID().toString())
		.clientId("mtls-client")
		.clientAuthenticationMethod(ClientAuthenticationMethod.TLS_CLIENT_AUTH)
		.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
		.scope("scope-a")
		.clientSettings(
				ClientSettings.builder()
						.x509CertificateSubjectDN("CN=mtls-client,OU=Spring Samples,O=Spring,C=US")
						.build()
		)
		.tokenSettings(
				TokenSettings.builder()
						.x509CertificateBoundAccessTokens(true)
						.build()
		)
		.build();