本站(springdoc.cn)中的内容来源于 spring.io ,原始版权归属于 spring.io。由 springboot.io - Spring Boot中文社区 进行翻译,整理。可供个人学习、研究,未经许可,不得进行任何转载、商用或与之相关的行为。 商标声明:Spring 是 Pivotal Software, Inc. 在美国以及其他国家的商标。 |
默配置
OAuth2AuthorizationServerConfiguration
是一个 @Configuration
,为OAuth2授权服务器提供最小的默认配置。
OAuth2AuthorizationServerConfiguration
使用 OAuth2AuthorizationServerConfigurer
来应用默认配置,并注册了一个由支持OAuth2授权服务器的所有基础设施组件组成的 SecurityFilterChain
@Bean
。
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(HttpSecurity) 是一个方便(静态)的实用方法,它将默认的 OAuth2 security configuration 应用到 HttpSecurity 。
|
OAuth2 授权服务器 SecurityFilterChain
@Bean
配置了以下默认协议端点。
只有在注册了 JWKSource<SecurityContext> @Bean 时,才会配置JWK Set端点。
|
下面的例子显示了如何使用 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>) 是一个方便(静态)的实用方法,可以用来注册一个 JwtDecoder @Bean ,它 是 OpenID Connect 1.0 UserInfo端点 和 OpenID Connect 1.0 Client Registration 端点 的必要条件。
|
下面的例子展示了如何注册一个 JwtDecoder
@Bean
。
@Bean
public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
}
OAuth2AuthorizationServerConfiguration
的主要意图是提供一个方便的方法来应用OAuth2授权服务器的最小默认配置。然而,在大多数情况下,需要对配置进行定制。
自定义配置
OAuth2AuthorizationServerConfigurer
提供了完全定制OAuth2授权服务器的 security configuration 的能力。它可以让你指定使用的核心组件—例如 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)
.tokenEndpoint(tokenEndpoint -> { }) (8)
.tokenIntrospectionEndpoint(tokenIntrospectionEndpoint -> { }) (9)
.tokenRevocationEndpoint(tokenRevocationEndpoint -> { }) (10)
.authorizationServerMetadataEndpoint(authorizationServerMetadataEndpoint -> { }) (11)
.oidc(oidc -> oidc
.providerConfigurationEndpoint(providerConfigurationEndpoint -> { }) (12)
.userInfoEndpoint(userInfoEndpoint -> { }) (13)
.clientRegistrationEndpoint(clientRegistrationEndpoint -> { }) (14)
);
return http.build();
}
1 | registeredClientRepository() : RegisteredClientRepository (必需的) 用于管理新的和现有的客户。 |
2 | authorizationService() : 用于管理新的和现有的授权的 OAuth2AuthorizationService 。 |
3 | authorizationConsentService() : OAuth2AuthorizationConsentService ,用于管理新的和现有的授权许可(Consent)。 |
4 | authorizationServerSettings() : 用于自定义OAuth2授权服务器的 configuration setting 的 AuthorizationServerSettings (必需的)。 |
5 | tokenGenerator() : OAuth2TokenGenerator ,用于生成OAuth2授权服务器支持的令牌。 |
6 | clientAuthentication() : OAuth2客户端认证的configurer。 |
7 | authorizationEndpoint() : OAuth2授权端点 的 configurer。 |
8 | tokenEndpoint() : OAuth2令牌端点 的 configurer。 |
9 | tokenIntrospectionEndpoint() : OAuth2 Token Introspection endpoint 端点的 configurer。 |
10 | tokenRevocationEndpoint() : OAuth2 Token Revocation 端点 的 configurer。 |
11 | authorizationServerMetadataEndpoint() : OAuth2授权服务器元数据端点 的 configurer。 |
12 | providerConfigurationEndpoint() : OpenID Connect 1.0 Provider 配置端点 的 configurer。 |
13 | userInfoEndpoint() : OpenID Connect 1.0 UserInfo 端点 的 configurer。 |
14 | clientRegistrationEndpoint() : OpenID Connect 1.0 客户端注册端点 的 configurer。 |
配置 Authorization Server Setting
AuthorizationServerSettings
包含 OAuth2 授权服务器的 configuration setting。它指定了协议端点的 URI
以及 issuer identifier。协议端点的默认URI如下。
public final class AuthorizationServerSettings extends AbstractSettings {
...
public static Builder builder() {
return new Builder()
.authorizationEndpoint("/oauth2/authorize")
.tokenEndpoint("/oauth2/token")
.tokenIntrospectionEndpoint("/oauth2/introspect")
.tokenRevocationEndpoint("/oauth2/revoke")
.jwkSetEndpoint("/oauth2/jwks")
.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")
.tokenEndpoint("/oauth2/v1/token")
.tokenIntrospectionEndpoint("/oauth2/v1/introspect")
.tokenRevocationEndpoint("/oauth2/v1/revoke")
.jwkSetEndpoint("/oauth2/v1/jwks")
.oidcUserInfoEndpoint("/connect/v1/userinfo")
.oidcClientRegistrationEndpoint("/connect/v1/register")
.build();
}
AuthorizationServerContext
是一个持有授权服务器运行环境信息的上下文对象。它提供了对 AuthorizationServerSettings
和 “current” issuer identifier 的访问。
如果 issuer identifier 没有在 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() : 设置 Consumer ,提供对默认和(可选)添加的 AuthenticationConverter List 的访问,允许添加、删除或定制特定的 AuthenticationConverter 的能力。 |
3 | authenticationProvider() : 添加一个用于验证 OAuth2ClientAuthenticationToken 的 AuthenticationProvider (主处理器)。 |
4 | authenticationProviders() : 设置 Consumer ,提供对默认和(可选)添加的 AuthenticationProvider List 的访问,允许添加、删除或定制特定的 AuthenticationProvider 。 |
5 | authenticationSuccessHandler() : AuthenticationSuccessHandler (后处理器),用于处理成功的客户端认证,并将 OAuth2ClientAuthenticationToken 与 SecurityContext 相关联。 |
6 | errorResponseHandler() : AuthenticationFailureHandler (后处理器),用于处理客户端认证失败并返回 OAuth2Error 响应。 |
OAuth2ClientAuthenticationConfigurer
配置 OAuth2ClientAuthenticationFilter
并将其注册到OAuth2授权服务器 SecurityFilterChain
@Bean
。OAuth2ClientAuthenticationFilter
是处理客户端认证请求的过滤器。
默认情况下,OAuth2令牌端点、OAuth2令牌内省(Introspection)端点和 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客户端断言(Assertion)验证
JwtClientAssertionDecoderFactory.DEFAULT_JWT_VALIDATOR_FACTORY
是默认工厂,为指定的 RegisteredClient
提供 OAuth2TokenValidator<Jwt>
,用于验证Jwt客户端断言(assertion)的 iss
、sub
、aud
、exp
和 nbf
claim。
JwtClientAssertionDecoderFactory
为 setJwtValidatorFactory()
提供了通过提供 Function<RegisteredClient, OAuth2TokenValidator<Jwt>
类型的自定义工厂来覆盖默认 Jwt
客户端断言(assertion)验证的能力。
JwtClientAssertionDecoderFactory 是 JwtClientAssertionAuthenticationProvider 使用的默认 JwtDecoderFactory ,它为指定的 RegisteredClient 提供一个 JwtDecoder ,用于在OAuth2客户端认证过程中认证Jwt Bearer Token。
|
定制 JwtClientAssertionDecoderFactory
的一个常见用例是验证Jwt客户端断言(assertion)中的额外claim。
下面的例子展示了如何用一个定制的 JwtClientAssertionDecoderFactory
来配置 JwtClientAssertionAuthenticationProvider
,它可以验证 Jwt
客户端断言(assertion)中的一个额外claim。
@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);
}
});
}