Spring 授权服务器配置模型

时间:2022-12-06 11:25:53

Spring 授权服务器配置模型

默认配置

​OAuth2AuthorizationServerConfiguration​​为 OAuth2 授权服务器提供最低默认配置。​​@Configuration​

​OAuth2AuthorizationServerConfiguration​​使用 OAuth2AuthorizationServerConfigurer 应用默认配置,并寄存器由支持OAuth2授权服务器的所有基础结构组件组成。​​SecurityFilterChain​​​​@Bean​

​OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(HttpSecurity)​​​是一种方便的 () 实用工具方法,用于应用默认的 OAuth2 安全配置。​​static​​​​HttpSecurity​

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

  • ​OAuth2 授权端点​
  • OAuth2 令牌端点
  • OAuth2 令牌侦测端点
  • OAuth2 令牌吊销端点
  • OAuth2 授权服务器元数据终结点
  • JWK 设置终结点

仅当 ais 已注册时,才会配置 JWK Set 终结点。​​JWKSource<SecurityContext>​​​​@Bean​

以下示例演示如何使用 应用最小默认配置:​​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在默认配置中处于禁用状态。以下示例演示如何通过初始化来启用 OpenID Connect 1.0:​​OidcConfigurer​

@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​​​​@Bean​

  • OpenID Connect 1.0 提供程序配置端点
  • OpenID Connect 1.0 UserInfo endpoint

默认情况下,OpenID Connect 1.0客户端注册终结点处于禁用状态,因为许多部署不需要动态客户端注册。

​OAuth2AuthorizationServerConfiguration.jwtDecoder(JWKSource<SecurityContext>)​​​是一种方便的 () 实用工具方法,可用于注册 OpenID Connect 1.0 UserInfo 端点和OpenID Connect 1.0客户端注册端点​static​​​​JwtDecoder​​​​@Bean​

以下示例演示如何注册:​​JwtDecoder​​​​@Bean​

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

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

自定义配置

​OAuth2AuthorizationServerConfigurer​​提供完全自定义 OAuth2 授权服务器的安全配置的功能。 它允许您指定要使用的核心组件 - 例如,RegisterClientRepository,OAuth2AuthorizationService,OAuth2TokenGenerator等。 此外,它还允许您自定义协议终端节点的请求处理逻辑,例如授权终端节点、令牌终端节点、令牌自检终端节点等。

​OAuth2AuthorizationServerConfigurer​​提供以下配置选项:

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

authorizationServerConfigurer
.registeredClientRepository(registeredClientRepository)
.authorizationService(authorizationService)
.authorizationConsentService(authorizationConsentService)
.authorizationServerSettings(authorizationServerSettings)
.tokenGenerator(tokenGenerator)
.clientAuthentication(clientAuthentication -> { })
.authorizationEndpoint(authorizationEndpoint -> { })
.tokenEndpoint(tokenEndpoint -> { })
.tokenIntrospectionEndpoint(tokenIntrospectionEndpoint -> { })
.tokenRevocationEndpoint(tokenRevocationEndpoint -> { })
.authorizationServerMetadataEndpoint(authorizationServerMetadataEndpoint -> { })
.oidc(oidc -> oidc
.providerConfigurationEndpoint(providerConfigurationEndpoint -> { })
.userInfoEndpoint(userInfoEndpoint -> { })
.clientRegistrationEndpoint(clientRegistrationEndpoint -> { })
);

return http.build();
}

​registeredClientRepository()​​​:用于管理新客户端和现有客户端的已注册客户端存储库(必需)。

​authorizationService()​​​:用于管理新授权和现有授权的OAuth2AuthorizationService。

​authorizationConsentService()​​​:OAuth2AuthorizationConsentService用于管理新的和现有的授权同意。

​authorizationServerSettings()​​​:用于自定义 OAuth2 授权服务器的配置设置的授权服务器设置(必需)。

​tokenGenerator()​​​:OAuth2TokenGenerator,用于生成 OAuth2 授权服务器支持的令牌。

​clientAuthentication()​​​:OAuth2 客户端身份验证的配置程序。

​authorizationEndpoint()​​​:OAuth2 授权端点的配置程序。

​tokenEndpoint()​​​:OAuth2 令牌端点的配置程序。

​tokenIntrospectionEndpoint()​​​:OAuth2 令牌侦测端点的配置程序。

​tokenRevocationEndpoint()​​​:OAuth2 令牌吊销端点的配置程序。

​authorizationServerMetadataEndpoint()​​​:OAuth2 授权服务器元数据端点的配置程序。

​providerConfigurationEndpoint()​​​:OpenID Connect 1.0 提供程序配置端点的配置程序。

​userInfoEndpoint()​​​:OpenID Connect 1.0 UserInfo 端点的配置程序。

​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")
.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​

如果未配置 颁发者标识符,则会从当前请求解析该标识符。​​AuthorizationServerSettings.builder().issuer(String)​

Theis 可通过 访问,它通过使用 a 将其与当前请求线程相关联。​​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)
.authenticationConverters(authenticationConvertersConsumer)
.authenticationProvider(authenticationProvider)
.authenticationProviders(authenticationProvidersConsumer)
.authenticationSuccessHandler(authenticationSuccessHandler)
.errorResponseHandler(errorResponseHandler)
);

return http.build();
}

​authenticationConverter()​​:将尝试从中提取客户端凭据时使用的(预处理器)添加到 的实例。​​AuthenticationConverter​​​​HttpServletRequest​​​​OAuth2ClientAuthenticationToken​

​authenticationConverters()​​​:设置提供对默认值和(可选)添加的访问权限,允许添加、删除或自定义特定内容。​​Consumer​​​​List​​​​AuthenticationConverter​​​​AuthenticationConverter​

​authenticationProvider()​​:添加用于身份验证的(主处理器)。​​AuthenticationProvider​​​​OAuth2ClientAuthenticationToken​

​authenticationProviders()​​​:设置提供对默认值和(可选)添加的访问权限,允许添加、删除或自定义特定内容。​​Consumer​​​​List​​​​AuthenticationProvider​​​​AuthenticationProvider​

​authenticationSuccessHandler()​​:用于处理成功的客户端身份验证并将其关联到的(后处理器)。​​AuthenticationSuccessHandler​​​​OAuth2ClientAuthenticationToken​​​​SecurityContext​

​errorResponseHandler()​​​:用于处理失败的客户端身份验证并返回OAuth2Error响应的(后处理器)。​​AuthenticationFailureHandler​

​OAuth2ClientAuthenticationConfigurer​​配置并使用 OAuth2 授权 server.is 处理客户端身份验证请求进行注册。​​OAuth2ClientAuthenticationFilter​​​​SecurityFilterChain​​​​@Bean​​​​OAuth2ClientAuthenticationFilter​​​​Filter​

默认情况下,OAuth2 令牌终端节点、OAuth2 令牌侦测终端节点和OAuth2 令牌吊销终端节点需要客户端身份验证。 支持的客户端身份验证方法包括,,,,和(公共客户端)。​​client_secret_basic​​​​client_secret_post​​​​private_key_jwt​​​​client_secret_jwt​​​​none​

​OAuth2ClientAuthenticationFilter​​配置了以下默认值:

  • AuthenticationConverter​— 由,,,和组成。DelegatingAuthenticationConverterJwtClientAssertionAuthenticationConverterClientSecretBasicAuthenticationConverterClientSecretPostAuthenticationConverterPublicClientAuthenticationConverter
  • AuthenticationManager​— 由、、和组成。AuthenticationManagerJwtClientAssertionAuthenticationProviderClientSecretAuthenticationProviderPublicClientAuthenticationProvider
  • AuthenticationSuccessHandler​— 将“经过身份验证”(当前)关联到的内部实现。OAuth2ClientAuthenticationTokenAuthenticationSecurityContext
  • AuthenticationFailureHandler​— 使用与 the关联的内部实现 返回 OAuth2 错误响应。OAuth2ErrorOAuth2AuthenticationException

自定义 JWT 客户端断言验证

​JwtClientAssertionDecoderFactory.DEFAULT_JWT_VALIDATOR_FACTORY​​是提供 anfor 的默认工厂 指定和 用于验证客户端断言的 ,,,和声明。​​OAuth2TokenValidator<Jwt>​​​​RegisteredClient​​​​iss​​​​sub​​​​aud​​​​exp​​​​nbf​​​​Jwt​

​JwtClientAssertionDecoderFactory​​提供通过提供 typeto 的自定义工厂来重写默认客户端断言验证的功能。​​Jwt​​​​Function<RegisteredClient, OAuth2TokenValidator<Jwt>>​​​​setJwtValidatorFactory()​

​JwtClientAssertionDecoderFactory​​​是默认使用的 提供 afor 指定和用于在 OAuth2 客户端身份验证期间对持有者令牌进行身份验证。​​JwtDecoderFactory​​​​JwtClientAssertionAuthenticationProvider​​​​JwtDecoder​​​​RegisteredClient​​​​Jwt​

自定义的一个常见用例是验证客户端断言中的其他声明。​​JwtClientAssertionDecoderFactory​​​​Jwt​

以下示例演示如何使用自定义验证客户端断言中的其他声明进行配置:​​JwtClientAssertionAuthenticationProvider​​​​JwtClientAssertionDecoderFactory​​​​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);
}
});
}