配置模型
默认配置
OAuth2AuthorizationServerConfiguration
是一个@Configuration
,为OAuth2授权服务器提供最小的默认配置。
OAuth2AuthorizationServerConfiguration
使用OAuth2AuthorizationServerConfigurer
来应用默认配置,并注册一个由支持OAuth2授权服务器的所有基础组件组成的SecurityFilterChain
@Bean
。
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(HttpSecurity) 是一个方便的(static )实用方法,将默认的OAuth2安全配置应用于HttpSecurity 。 |
SecurityFilterChain
@Bean
配置了以下默认的协议端点:
只有在注册了JWKSource<SecurityContext> @Bean 时,才会配置JWK集合端点。 |
以下示例显示了如何使用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授权要求资源所有者进行身份验证。因此,除了默认的OAuth2安全配置外,必须配置用户身份验证机制。 |
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客户端注册端点,因为许多部署不需要动态客户端注册。 |
OAuth2AuthorizationServerConfiguration.jwtDecoder(JWKSource<SecurityContext>) 是一个方便的(static )实用方法,可用于注册JwtDecoder @Bean ,这是OpenID Connect 1.0用户信息端点和OpenID Connect 1.0客户端注册端点所必需的。 |
以下示例显示了如何注册一个JwtDecoder
@Bean
:
@Bean
public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
}
OAuth2AuthorizationServerConfiguration
的主要目的是提供一种便捷的方法,应用OAuth2授权服务器的最小默认配置。然而,在大多数情况下,将需要自定义配置。
自定义配置
OAuth2AuthorizationServerConfigurer
提供了完全定制OAuth2授权服务器安全配置的能力。它允许您指定要使用的核心组件 - 例如,RegisteredClientRepository
,OAuth2AuthorizationService
,OAuth2TokenGenerator
等。此外,它还允许您定制协议端点的请求处理逻辑 - 例如,授权端点,设备授权端点,设备验证端点,令牌端点,令牌内省端点等。
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() : 用于管理新建和现有客户端的RegisteredClientRepository (必需)。 |
2 | authorizationService() : 用于管理新建和现有授权的OAuth2AuthorizationService 。 |
3 | authorizationConsentService() : 用于管理新建和现有授权同意的OAuth2AuthorizationConsentService 。 |
4 | authorizationServerSettings() : 用于自定义配置OAuth2授权服务器的AuthorizationServerSettings (必需)。 |
5 | tokenGenerator() : 用于生成OAuth2授权服务器支持的令牌的OAuth2TokenGenerator 。 |
6 | clientAuthentication() : 用于配置OAuth2客户端认证的配置器。 |
7 | authorizationEndpoint() : 用于OAuth2授权端点的配置器。 |
8 | deviceAuthorizationEndpoint() : 用于OAuth2设备授权端点的配置器。 |
9 | deviceVerificationEndpoint() : 用于OAuth2设备验证端点的配置器。 |
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用户信息端点的配置器。 |
17 | clientRegistrationEndpoint() : 用于OpenID Connect 1.0客户端注册端点的配置器。 |
配置授权服务器设置
AuthorizationServerSettings
包含了OAuth2授权服务器的配置设置。它指定了协议端点的URI
以及发行者标识符。协议端点的默认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 是一个必需的组件。 |
@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 访问,后者通过使用ThreadLocal 将其与当前请求线程关联。 |
配置客户端认证
OAuth2ClientAuthenticationConfigurer
提供了自定义OAuth2客户端认证的能力。它定义了扩展点,让您可以自定义客户端认证请求的预处理、主处理和后处理逻辑。
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() :添加一个AuthenticationConverter (预处理器),用于尝试从HttpServletRequest 中提取客户端凭据到OAuth2ClientAuthenticationToken 实例。 |
2 | authenticationConverters() :设置提供访问默认和(可选)添加的AuthenticationConverter 列表的Consumer ,允许添加、删除或自定义特定的AuthenticationConverter 。 |
3 | authenticationProvider() :添加一个AuthenticationProvider (主处理器),用于对OAuth2ClientAuthenticationToken 进行身份验证。 |
4 | authenticationProviders() :设置提供访问默认和(可选)添加的AuthenticationProvider 列表的Consumer ,允许添加、删除或自定义特定的AuthenticationProvider 。 |
5 | authenticationSuccessHandler() :用于处理成功的客户端认证并将OAuth2ClientAuthenticationToken 关联到SecurityContext 的AuthenticationSuccessHandler (后处理器)。 |
6 | errorResponseHandler() :用于处理失败的客户端认证并返回OAuth2Error 响应的AuthenticationFailureHandler (后处理器)。 |
OAuth2ClientAuthenticationConfigurer
配置了OAuth2ClientAuthenticationFilter
并将其注册到OAuth2授权服务器SecurityFilterChain
的@Bean
中。OAuth2ClientAuthenticationFilter
是处理客户端认证请求的Filter
。
默认情况下,OAuth2令牌端点、OAuth2令牌内省端点和OAuth2令牌撤销端点需要客户端认证。支持的客户端认证方法包括client_secret_basic
、client_secret_post
、private_key_jwt
、client_secret_jwt
和none
(公共客户端)。
OAuth2ClientAuthenticationFilter
配置了以下默认值:
-
AuthenticationConverter
— 由JwtClientAssertionAuthenticationConverter
、ClientSecretBasicAuthenticationConverter
、ClientSecretPostAuthenticationConverter
和PublicClientAuthenticationConverter
组成的DelegatingAuthenticationConverter
。 -
AuthenticationManager
— 由JwtClientAssertionAuthenticationProvider
、ClientSecretAuthenticationProvider
和PublicClientAuthenticationProvider
组成的AuthenticationManager
。 -
AuthenticationSuccessHandler
— 一个内部实现,将“经过身份验证”的OAuth2ClientAuthenticationToken
(当前Authentication
)关联到SecurityContext
。 -
AuthenticationFailureHandler
— 一个内部实现,使用与OAuth2AuthenticationException
关联的OAuth2Error
来返回OAuth2错误响应。
自定义Jwt客户端断言验证
JwtClientAssertionDecoderFactory.DEFAULT_JWT_VALIDATOR_FACTORY
是默认工厂,为指定的RegisteredClient
提供一个OAuth2TokenValidator<Jwt>
,用于验证Jwt
客户端断言的iss
、sub
、aud
、exp
和nbf
声明。
JwtClientAssertionDecoderFactory
提供了通过提供类型为Function<RegisteredClient, OAuth2TokenValidator<Jwt>>
的自定义工厂来覆盖默认的Jwt
客户端断言验证的能力,方法是调用setJwtValidatorFactory()
。
JwtClientAssertionDecoderFactory 是JwtClientAssertionAuthenticationProvider 使用的默认JwtDecoderFactory ,为指定的RegisteredClient 提供一个JwtDecoder ,用于在OAuth2客户端认证期间对Jwt Bearer Token进行身份验证。 |
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);
}
});
}