概述
介绍 Spring 授权服务器
Spring Authorization Server 是一个框架,提供了OAuth 2.1和OpenID Connect 1.0规范以及其他相关规范的实现。它建立在Spring Security之上,为构建 OpenID Connect 1.0 Identity Providers 和 OAuth2 Authorization Server 产品提供安全、轻量级和可定制的基础。
功能列表
Spring Authorization Server 支持以下特性:
类别 | 特征 | 相关规格 |
授权码用户同意客户凭证刷新令牌 | OAuth 2.1 授权框架(草案)授权码授予客户凭证授予刷新令牌授予OpenID Connect Core 1.0(规范)授权码流程 | |
自包含 (JWT)参考(不透明) | JSON Web 令牌 (JWT) ( RFC 7519 )JSON Web 签名 (JWS) ( RFC 7515 ) | |
| OAuth 2.1 授权框架(客户端身份验证)用于 OAuth 2.0 客户端身份验证的 JSON Web 令牌 (JWT) 配置文件 ( RFC 7523 )OAuth 公共客户端 (PKCE) 的代码交换证明密钥 ( RFC 7636 ) | |
OAuth2 授权端点OAuth2 令牌端点OAuth2 令牌自省端点OAuth2 令牌撤销端点OAuth2 授权服务器元数据端点JWK 设置端点OpenID Connect 1.0 提供者配置端点OpenID Connect 1.0 用户信息端点OpenID Connect 1.0 客户端注册端点 | OAuth 2.1 授权框架(草案)授权端点令牌端点OAuth 2.0 令牌自省 ( RFC 7662 )OAuth 2.0 令牌撤销 ( RFC 7009 )OAuth 2.0 授权服务器元数据 ( RFC 8414 )JSON 网络密钥 (JWK) ( RFC 7517 )OpenID Connect Discovery 1.0(规范)提供者配置端点OpenID Connect Core 1.0(规范)用户信息端点OpenID Connect 动态客户端注册 1.0(规范)客户注册端点客户端配置端点 |
获得帮助
社区
欢迎来到Spring 安全社区。Spring Authorization Server 是 Spring Security 团队主导的开源项目。如果您需要有关 Spring Authorization Server 的帮助,我们随时为您提供帮助。
资源
以下是获得帮助的一些最佳方式:
- 尝试操作指南。他们为最常见的问题提供解决方案。
- 了解 Spring Authorization Server 构建的 Spring Security 基础知识。如果您刚开始使用 Spring Security,请查看参考文档或尝试其中一个示例。
- 通读本文档。
- 尝试我们的众多示例应用程序之一。
- spring-security使用标签在 Stack Overflow 上提问。
- 在GitHub 上报告错误和增强请求。
入门
如果您刚刚开始使用 Spring Authorization Server,以下部分将引导您创建您的第一个应用程序。
系统要求
Spring Authorization Server 需要 Java 8 或更高版本的运行时环境。
安装 Spring 授权服务器
Spring Authorization Server 可以在您已经使用Spring Security的任何地方使用。
开始使用 Spring Authorization Server 的最简单方法是创建基于Spring Boot的应用程序。您可以使用start.spring.io生成基本项目或使用默认授权服务器示例作为指导。然后将 Spring Authorization Server 添加为依赖项,如下例所示:
gradle
implementation "org.springframework.security:spring-security-oauth2-authorization-server:0.3.0"
maven
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-authorization-server</artifactId>
<version>0.3.0</version>
</dependency>
开发您的第一个应用程序
要开始,您需要@Bean
在 Spring 中定义为 a 的最少必需组件@Configuration
。这些组件可以定义如下:
@Configuration
public class SecurityConfig {
@Bean 【1】
@Order(1)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http)
throws Exception {
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
http
// Redirect to the login page when not authenticated from the
// authorization endpoint
.exceptionHandling((exceptions) -> exceptions
.authenticationEntryPoint(
new LoginUrlAuthenticationEntryPoint("/login"))
);
return http.build();
}
@Bean 【2】
@Order(2)
public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http)
throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.anyRequest().authenticated()
)
// Form login handles the redirect to the login page from the
// authorization server filter chain
.formLogin(Customizer.withDefaults());
return http.build();
}
@Bean 【3】
public UserDetailsService userDetailsService() {
UserDetails userDetails = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(userDetails);
}
@Bean 【4】
public RegisteredClientRepository registeredClientRepository() {
RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString())
.clientId("messaging-client")
.clientSecret("{noop}secret")
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
.redirectUri("http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc")
.redirectUri("http://127.0.0.1:8080/authorized")
.scope(OidcScopes.OPENID)
.scope("message.read")
.scope("message.write")
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
.build();
return new InMemoryRegisteredClientRepository(registeredClient);
}
@Bean 【5】
public JWKSource<SecurityContext> jwkSource() {
KeyPair keyPair = generateRsaKey();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
RSAKey rsaKey = new RSAKey.Builder(publicKey)
.privateKey(privateKey)
.keyID(UUID.randomUUID().toString())
.build();
JWKSet jwkSet = new JWKSet(rsaKey);
return new ImmutableJWKSet<>(jwkSet);
}
【6】
private static KeyPair generateRsaKey() {
KeyPair keyPair;
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
keyPair = keyPairGenerator.generateKeyPair();
}
catch (Exception ex) {
throw new IllegalStateException(ex);
}
return keyPair;
}
@Bean 【7】
public ProviderSettings providerSettings() {
return ProviderSettings.builder().build();
}
}
这是快速入门的最低配置。要了解每个组件的用途,请参阅以下说明:
1 | 协议端点的 Spring Security 过滤器链。 |
2 | 用于身份验证的 Spring Security 过滤器链。 |
3 | UserDetailsService用于检索用户进行身份验证的实例。 |
4 | RegisteredClientRepository用于管理客户端的实例。 |
5 |
|
6 | 启动时生成的带有密钥的实例 |
7 | ProviderSettings配置 Spring Authorization Server的实例。 |
配置模型
默认配置
OAuth2AuthorizationServerConfiguration
是@Configuration
为 OAuth2 授权服务器提供最小默认配置的一种。
OAuth2AuthorizationServerConfiguration
用于OAuth2AuthorizationServerConfigurer应用默认配置并注册一个SecurityFilterChain
@Bean
由所有支持 OAuth2 授权服务器的基础架构组件组成的组件。
OAuth2 授权服务器SecurityFilterChain
@Bean
配置有以下默认协议端点:
- OAuth2 授权端点
- OAuth2 令牌端点
- OAuth2 令牌自省端点
- OAuth2 令牌撤销端点
- OAuth2 授权服务器元数据端点
- JWK 设置端点
- OpenID Connect 1.0 提供者配置端点
- OpenID Connect 1.0 UserInfo 端点
以下示例显示了如何使用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);
}
}
下面的例子展示了如何注册一个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<HttpSecurity> authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer<>();
http.apply(authorizationServerConfigurer);
authorizationServerConfigurer
.registeredClientRepository(registeredClientRepository) 【1】
.authorizationService(authorizationService) 【2】
.authorizationConsentService(authorizationConsentService) 【3】
.providerSettings(providerSettings) 【4】
.tokenGenerator(tokenGenerator) 【5】
.clientAuthentication(clientAuthentication -> { }) 【6】
.authorizationEndpoint(authorizationEndpoint -> { }) 【7】
.tokenEndpoint(tokenEndpoint -> { }) 【8】
.tokenIntrospectionEndpoint(tokenIntrospectionEndpoint -> { }) 【9】
.tokenRevocationEndpoint(tokenRevocationEndpoint -> { }) 【10】
.oidc(oidc -> oidc
.userInfoEndpoint(userInfoEndpoint -> { }) 【11】
.clientRegistrationEndpoint(clientRegistrationEndpoint -> { }) 【12】
);
return http.build();
}
1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
配置提供程序设置
ProviderSettings
包含 OAuth2 授权服务器(提供者)的配置设置。它URI
为协议端点指定了 以及颁发者标识符。协议端点的默认值URI
如下:
public final class ProviderSettings 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");
}
...
}
以下示例显示了如何自定义配置设置并注册ProviderSettings
@Bean
:
@Bean
public ProviderSettings providerSettings() {
return ProviderSettings.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();
}
这ProviderContext
是一个包含有关提供者信息的上下文对象。它提供ProviderSettings
对“当前”发行者标识符的访问。
配置客户端身份验证
OAuth2ClientAuthenticationConfigurer
提供自定义OAuth2 客户端身份验证的能力。它定义了扩展点,允许您自定义客户端身份验证请求的预处理、主处理和后处理逻辑。
OAuth2ClientAuthenticationConfigurer
提供以下配置选项:
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer<HttpSecurity> authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer<>();
http.apply(authorizationServerConfigurer);
authorizationServerConfigurer
.clientAuthentication(clientAuthentication ->
clientAuthentication
.authenticationConverter(authenticationConverter) 【1】
.authenticationProvider(authenticationProvider) 【2】
.authenticationSuccessHandler(authenticationSuccessHandler) 【3】
.errorResponseHandler(errorResponseHandler) 【4】
);
return http.build();
}
1 |
|
2 |
|
3 |
|
4 |
|
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**
— ADelegatingAuthenticationConverter
由JwtClientAssertionAuthenticationConverter
、ClientSecretBasicAuthenticationConverter
、ClientSecretPostAuthenticationConverter
和组成PublicClientAuthenticationConverter
。**AuthenticationManager**
—AuthenticationManager
由JwtClientAssertionAuthenticationProvider
、ClientSecretAuthenticationProvider
和组成PublicClientAuthenticationProvider
。**AuthenticationSuccessHandler**
— 将“已验证”OAuth2ClientAuthenticationToken
(当前Authentication
)与SecurityContext
.**AuthenticationFailureHandler**
— 使用与OAuth2Error
关联的内部实现OAuth2AuthenticationException
来返回 OAuth2 错误响应。
核心模型/组件
注册客户
ARegisteredClient
是向授权服务器注册的客户端的表示。客户端必须先向授权服务器注册,然后才能启动授权授予流程,例如authorization_code
或client_credentials
。
在客户端注册期间,客户端被分配了一个唯一的客户端标识符,(可选)一个客户端机密(取决于客户端类型),以及与其唯一客户端标识符相关联的元数据。客户端元数据的范围可以从面向人的显示字符串(例如客户端名称)到特定于协议流的项目(例如有效重定向 URI 的列表)。
客户端的主要目的是请求访问受保护的资源。客户端首先通过与授权服务器进行身份验证并提供授权许可来请求访问令牌。授权服务器对客户端和授权授予进行身份验证,如果它们有效,则颁发访问令牌。客户端现在可以通过提供访问令牌从资源服务器请求受保护的资源。
以下示例显示如何配置RegisteredClient
允许执行授权代码授权流程以请求访问令牌:
RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString())
.clientId("client-a")
.clientSecret("{noop}secret")
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.redirectUri("http://127.0.0.1:8080/authorized")
.scope("scope-a")
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
.build();
Spring Security 的OAuth2 Client 支持中对应的配置是:
spring:
security:
oauth2:
client:
registration:
client-a:
provider: spring
client-id: client-a
client-secret: secret
authorization-grant-type: authorization_code
redirect-uri: "http://127.0.0.1:8080/authorized"
scope: scope-a
provider:
spring:
issuer-uri: http://localhost:9000
ARegisteredClient
具有与其唯一客户端标识符关联的元数据(属性),定义如下:
public class RegisteredClient implements Serializable {
private String id; 【1】
private String clientId; 【2】
private Instant clientIdIssuedAt; 【3】
private String clientSecret; 【4】
private Instant clientSecretExpiresAt; 【5】
private String clientName; 【6】
private Set<ClientAuthenticationMethod> clientAuthenticationMethods; 【7】
private Set<AuthorizationGrantType> authorizationGrantTypes; 【8】
private Set<String> redirectUris; 【9】
private Set<String> scopes; 【10】
private ClientSettings clientSettings; 【11】
private TokenSettings tokenSettings; 【12】
...
}
1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
RegisteredClientRepository
这RegisteredClientRepository
是可以注册新客户端和查询现有客户端的中心组件。其他组件在遵循特定协议流时使用它,例如客户端身份验证、授权授予处理、令牌自省、动态客户端注册等。
提供的RegisteredClientRepository
areInMemoryRegisteredClientRepository
和JdbcRegisteredClientRepository
. 该InMemoryRegisteredClientRepository
实现将RegisteredClient
实例存储在内存中,建议仅在开发和测试期间使用。 JdbcRegisteredClientRepository
是一个 JDBC 实现,它RegisteredClient
使用JdbcOperations
.
下面的例子展示了如何注册一个RegisteredClientRepository
@Bean
:
@Bean
public RegisteredClientRepository registeredClientRepository() {
List<RegisteredClient> registrations = ...
return new InMemoryRegisteredClientRepository(registrations);
}
或者,您可以RegisteredClientRepository
通过以下方式配置OAuth2AuthorizationServerConfigurer:
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer<HttpSecurity> authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer<>();
http.apply(authorizationServerConfigurer);
authorizationServerConfigurer
.registeredClientRepository(registeredClientRepository);
...
return http.build();
}
OAuth2授权
AnOAuth2Authorization
是 OAuth2 授权的表示形式,在授权授予类型的情况下,它保存与资源所有者或自身授予客户端的授权相关的状态。client_credentials
在成功完成授权授予流程后,将OAuth2Authorization
创建 an 并将 an OAuth2AccessToken、 an (可选)OAuth2RefreshToken和特定于已执行授权授予类型的附加状态相关联。
OAuth2Token与授权关联的实例会OAuth2Authorization
有所不同,具体取决于授权授予类型。
对于 OAuth2 authorization_code grant, an OAuth2AuthorizationCode
、 anOAuth2AccessToken
和 an (可选)OAuth2RefreshToken
相关联。
对于 OpenID Connect 1.0 authorization_code grant, an OAuth2AuthorizationCode
、 an OidcIdToken、 anOAuth2AccessToken
和 an (可选)OAuth2RefreshToken
相关联。
对于 OAuth2 client_credentials grant,只有 anOAuth2AccessToken
关联。
OAuth2Authorization
其属性定义如下:
public class OAuth2Authorization implements Serializable {
private String id; 【1】
private String registeredClientId; 【2】
private String principalName; 【3】
private AuthorizationGrantType authorizationGrantType; 【4】
private Map<Class<? extends OAuth2Token>, Token<?>> tokens; 【5】
private Map<String, Object> attributes; 【6】
...
}
1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
OAuth2Authorization`及其关联`OAuth2Token`的实例具有固定的生命周期。新发行`OAuth2Token`的发行处于活动状态,并在到期或失效(撤销)时变为非活动状态。当`OAuth2Authorization`所有关联`OAuth2Token`的实例都处于非活动状态时,它(隐式)处于非活动状态。每个`OAuth2Token`都保存在一个中,它为、和`OAuth2Authorization.Token`提供访问器。`isExpired()``isInvalidated()``isActive()
OAuth2Authorization.Token
还提供getClaims()
,它返回与 . 关联的声明(如果有)OAuth2Token
。
OAuth2AuthorizationService
这OAuth2AuthorizationService
是存储新授权和查询现有授权的中心组件。其他组件在遵循特定协议流时使用它——例如,客户端身份验证、授权授予处理、令牌自省、令牌撤销、动态客户端注册等。
提供的OAuth2AuthorizationService
areInMemoryOAuth2AuthorizationService
和JdbcOAuth2AuthorizationService
. 该InMemoryOAuth2AuthorizationService
实现将OAuth2Authorization
实例存储在内存中,建议仅在开发和测试期间使用。 JdbcOAuth2AuthorizationService
是一个 JDBC 实现,它OAuth2Authorization
使用JdbcOperations
.
以下示例显示了如何注册OAuth2AuthorizationService
@Bean
:
@Bean
public OAuth2AuthorizationService authorizationService() {
return new InMemoryOAuth2AuthorizationService();
}
或者,您可以OAuth2AuthorizationService
通过以下方式配置OAuth2AuthorizationServerConfigurer:
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer<HttpSecurity> authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer<>();
http.apply(authorizationServerConfigurer);
authorizationServerConfigurer
.authorizationService(authorizationService);
...
return http.build();
}
OAuth2AuthorizationConsent
AnOAuth2AuthorizationConsent
是来自OAuth2 授权请求流的授权“同意”(决定)的表示- 例如,授权,它持有资源所有者authorization_code
授予客户端的权限。
当授权对客户端的访问时,资源所有者可以仅授予客户端请求的权限的子集。典型的用例是authorization_code
授权流程,其中客户端请求范围,资源所有者授予(或拒绝)对所请求范围的访问权限。
在完成 OAuth2 授权请求流程后,将OAuth2AuthorizationConsent
创建(或更新)一个并将授予的权限与客户端和资源所有者相关联。
OAuth2AuthorizationConsent
其属性定义如下:
public final class OAuth2AuthorizationConsent implements Serializable {
private final String registeredClientId; 【1】
private final String principalName; 【2】
private final Set<GrantedAuthority> authorities; 【3】
...
}
1 |
|
2 |
|
3 |
|
OAuth2AuthorizationConsentService
这OAuth2AuthorizationConsentService
是存储新授权同意和查询现有授权同意的中心组件。它主要由实现 OAuth2 授权请求流程的组件使用——例如,authorization_code
授权。
提供的OAuth2AuthorizationConsentService
areInMemoryOAuth2AuthorizationConsentService
和JdbcOAuth2AuthorizationConsentService
. 该InMemoryOAuth2AuthorizationConsentService
实现将OAuth2AuthorizationConsent
实例存储在内存中,建议仅用于开发和测试。 JdbcOAuth2AuthorizationConsentService
是一个 JDBC 实现,它OAuth2AuthorizationConsent
使用JdbcOperations
.
以下示例显示了如何注册OAuth2AuthorizationConsentService
@Bean
:
@Bean
public OAuth2AuthorizationConsentService authorizationConsentService() {
return new InMemoryOAuth2AuthorizationConsentService();
}
或者,您可以OAuth2AuthorizationConsentService
通过以下方式配置OAuth2AuthorizationServerConfigurer:
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer<HttpSecurity> authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer<>();
http.apply(authorizationServerConfigurer);
authorizationServerConfigurer
.authorizationConsentService(authorizationConsentService);
...
return http.build();
}
OAuth2TokenContext
AnOAuth2TokenContext
是一个上下文对象,它保存与 an 关联的信息,OAuth2Token
并由OAuth2TokenGenerator和OAuth2TokenCustomizer使用。
OAuth2TokenContext
提供以下访问器:
public interface OAuth2TokenContext extends Context {
default RegisteredClient getRegisteredClient() ... 【1】
default <T extends Authentication> T getPrincipal() ... 【2】
default ProviderContext getProviderContext() ... 【3】
@Nullable
default OAuth2Authorization getAuthorization() ... 【4】
default Set<String> getAuthorizedScopes() ... 【5】
default OAuth2TokenType getTokenType() ... 【6】
default AuthorizationGrantType getAuthorizationGrantType() ... 【7】
default <T extends Authentication> T getAuthorizationGrant() ... 【8】
...
}
1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
OAuth2令牌生成器
AnOAuth2TokenGenerator
负责从提供的OAuth2TokenContextOAuth2Token
中包含的信息生成一个。
生成的OAuth2Token
主要取决于OAuth2TokenType
.OAuth2TokenContext
例如,当value
forOAuth2TokenType
是:
code
,然后OAuth2AuthorizationCode
生成。access_token
,然后OAuth2AccessToken
生成。refresh_token
,然后OAuth2RefreshToken
生成。id_token
,然后OidcIdToken
生成。
此外,生成的格式会OAuth2AccessToken
有所不同,具体取决于为RegisteredClientTokenSettings.getAccessTokenFormat()
配置的内容。如果格式为(默认),则生成 a。如果格式为,则生成“不透明”令牌。OAuth2TokenFormat.SELF_CONTAINED``Jwt``OAuth2TokenFormat.REFERENCE
最后,如果生成的OAuth2Token
具有一组声明和实现ClaimAccessor
,则可以从OAuth2Authorization.Token.getClaims()访问声明。
OAuth2TokenGenerator
主要由实现授权授予处理的组件使用,例如authorization_code
、client_credentials
和refresh_token
。
提供的实现是OAuth2AccessTokenGenerator
、OAuth2RefreshTokenGenerator
和JwtGenerator
。生成一个“OAuth2AccessTokenGenerator
不透明”( OAuth2TokenFormat.REFERENCE
) 访问令牌,并JwtGenerator
生成一个Jwt
( OAuth2TokenFormat.SELF_CONTAINED
)。
提供OAuth2TokenGenerator
了极大的灵活性,因为它可以支持access_token
和的任何自定义令牌格式refresh_token
。
以下示例显示了如何注册OAuth2TokenGenerator
@Bean
:
@Bean
public OAuth2TokenGenerator<?> tokenGenerator() {
JwtEncoder jwtEncoder = ...
JwtGenerator jwtGenerator = new JwtGenerator(jwtEncoder);
OAuth2AccessTokenGenerator accessTokenGenerator = new OAuth2AccessTokenGenerator();
OAuth2RefreshTokenGenerator refreshTokenGenerator = new OAuth2RefreshTokenGenerator();
return new DelegatingOAuth2TokenGenerator(
jwtGenerator, accessTokenGenerator, refreshTokenGenerator);
}
或者,您可以OAuth2TokenGenerator
通过以下方式配置OAuth2AuthorizationServerConfigurer:
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer<HttpSecurity> authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer<>();
http.apply(authorizationServerConfigurer);
authorizationServerConfigurer
.tokenGenerator(tokenGenerator);
...
return http.build();
}
OAuth2TokenCustomizer
AnOAuth2TokenCustomizer
提供了自定义 属性的能力,这些属性OAuth2Token
可以在提供的OAuth2TokenContext中访问。OAuth2TokenGenerator使用它来让它在OAuth2Token
生成之前自定义属性。
具有( )OAuth2TokenCustomizer<OAuth2TokenClaimsContext>
的泛型类型的声明提供了自定义“不透明”声明的能力。 提供对 的访问,允许添加、替换和删除声明。OAuth2TokenClaimsContext``implements OAuth2TokenContext``OAuth2AccessToken``OAuth2TokenClaimsContext.getClaims()``OAuth2TokenClaimsSet.Builder
下面的例子展示了如何实现一个OAuth2TokenCustomizer<OAuth2TokenClaimsContext>
并用一个配置它OAuth2AccessTokenGenerator
:
@Bean
public OAuth2TokenGenerator<?> tokenGenerator() {
JwtEncoder jwtEncoder = ...
JwtGenerator jwtGenerator = new JwtGenerator(jwtEncoder);
OAuth2AccessTokenGenerator accessTokenGenerator = new OAuth2AccessTokenGenerator();
accessTokenGenerator.setAccessTokenCustomizer(accessTokenCustomizer());
OAuth2RefreshTokenGenerator refreshTokenGenerator = new OAuth2RefreshTokenGenerator();
return new DelegatingOAuth2TokenGenerator(
jwtGenerator, accessTokenGenerator, refreshTokenGenerator);
}
@Bean
public OAuth2TokenCustomizer<OAuth2TokenClaimsContext> accessTokenCustomizer() {
return context -> {
OAuth2TokenClaimsSet.Builder claims = context.getClaims();
// Customize claims
};
}
具有( )OAuth2TokenCustomizer<JwtEncodingContext>
泛型类型的声明提供了自定义标头和声明的能力。 提供对 的访问,允许添加、替换和删除标题。 提供对 的访问,允许添加、替换和删除声明。JwtEncodingContext``implements OAuth2TokenContext``Jwt``JwtEncodingContext.getHeaders()``JwsHeader.Builder``JwtEncodingContext.getClaims()``JwtClaimsSet.Builder
以下示例显示了如何实现 anOAuth2TokenCustomizer<JwtEncodingContext>
并使用 a 对其进行配置JwtGenerator
:
@Bean
public OAuth2TokenGenerator<?> tokenGenerator() {
JwtEncoder jwtEncoder = ...
JwtGenerator jwtGenerator = new JwtGenerator(jwtEncoder);
jwtGenerator.setJwtCustomizer(jwtCustomizer());
OAuth2AccessTokenGenerator accessTokenGenerator = new OAuth2AccessTokenGenerator();
OAuth2RefreshTokenGenerator refreshTokenGenerator = new OAuth2RefreshTokenGenerator();
return new DelegatingOAuth2TokenGenerator(
jwtGenerator, accessTokenGenerator, refreshTokenGenerator);
}
@Bean
public OAuth2TokenCustomizer<JwtEncodingContext> jwtCustomizer() {
return context -> {
JwsHeader.Builder headers = context.getHeaders();
JwtClaimsSet.Builder claims = context.getClaims();
if (context.getTokenType().equals(OAuth2TokenType.ACCESS_TOKEN)) {
// Customize headers/claims for access_token
} else if (context.getTokenType().getValue().equals(OidcParameterNames.ID_TOKEN)) {
// Customize headers/claims for id_token
}
};
}
协议端点
OAuth2 授权端点
OAuth2AuthorizationEndpointConfigurer
提供自定义OAuth2 授权端点的能力。它定义了扩展点,让您可以自定义OAuth2 授权请求的预处理、主处理和后处理逻辑。
OAuth2AuthorizationEndpointConfigurer
提供以下配置选项:
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer<HttpSecurity> authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer<>();
http.apply(authorizationServerConfigurer);
authorizationServerConfigurer
.authorizationEndpoint(authorizationEndpoint ->
authorizationEndpoint
.authorizationRequestConverter(authorizationRequestConverter) 【1】
.authenticationProvider(authenticationProvider) 【2】
.authorizationResponseHandler(authorizationResponseHandler) 【3】
.errorResponseHandler(errorResponseHandler) 【4】
.consentPage("/oauth2/v1/authorize") 【5】
);
return http.build();
}
1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
OAuth2AuthorizationEndpointConfigurer
配置OAuth2AuthorizationEndpointFilter
并注册到 OAuth2 授权服务器SecurityFilterChain
@Bean
。 OAuth2AuthorizationEndpointFilter
是Filter
处理 OAuth2 授权请求(和同意)的。
OAuth2AuthorizationEndpointFilter
配置有以下默认值:
**AuthenticationConverter**
— 一个OAuth2AuthorizationCodeRequestAuthenticationConverter
。**AuthenticationManager**
—AuthenticationManager
由 组成OAuth2AuthorizationCodeRequestAuthenticationProvider
。**AuthenticationSuccessHandler**
— 处理“已验证”OAuth2AuthorizationCodeRequestAuthenticationToken
并返回OAuth2AuthorizationResponse
.**AuthenticationFailureHandler**
— 使用与OAuth2Error
关联的内部实现OAuth2AuthorizationCodeRequestAuthenticationException
并返回OAuth2Error
响应。
OAuth2 令牌端点
OAuth2TokenEndpointConfigurer
提供自定义OAuth2 令牌端点的能力。它定义了扩展点,让您可以自定义OAuth2 访问令牌请求的预处理、主处理和后处理逻辑。
OAuth2TokenEndpointConfigurer
提供以下配置选项:
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer<HttpSecurity> authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer<>();
http.apply(authorizationServerConfigurer);
authorizationServerConfigurer
.tokenEndpoint(tokenEndpoint ->
tokenEndpoint
.accessTokenRequestConverter(accessTokenRequestConverter) 【1】
.authenticationProvider(authenticationProvider) 【2】
.accessTokenResponseHandler(accessTokenResponseHandler) 【3】
.errorResponseHandler(errorResponseHandler) 【4】
);
return http.build();
}
1 |
|
2 |
|
3 |
|
4 |
|
OAuth2TokenEndpointConfigurer
配置OAuth2TokenEndpointFilter
并注册到 OAuth2 授权服务器SecurityFilterChain
@Bean
。 OAuth2TokenEndpointFilter
是Filter
处理 OAuth2 访问令牌请求的。
支持的授权授权类型是authorization_code
、refresh_token
和client_credentials
。
OAuth2TokenEndpointFilter
配置有以下默认值:
**AuthenticationConverter**
— ADelegatingAuthenticationConverter
由OAuth2AuthorizationCodeAuthenticationConverter
、OAuth2RefreshTokenAuthenticationConverter
和组成OAuth2ClientCredentialsAuthenticationConverter
。**AuthenticationManager**
—AuthenticationManager
由OAuth2AuthorizationCodeAuthenticationProvider
、OAuth2RefreshTokenAuthenticationProvider
和组成OAuth2ClientCredentialsAuthenticationProvider
。**AuthenticationSuccessHandler**
— 处理 anOAuth2AccessTokenAuthenticationToken
并返回OAuth2AccessTokenResponse
.**AuthenticationFailureHandler**
— 使用与OAuth2Error
关联的内部实现OAuth2AuthenticationException
并返回OAuth2Error
响应。
OAuth2 令牌自省端点
OAuth2TokenIntrospectionEndpointConfigurer
提供自定义OAuth2 Token Introspection 端点的能力。它定义了扩展点,让您可以自定义OAuth2 自省请求的预处理、主处理和后处理逻辑。
OAuth2TokenIntrospectionEndpointConfigurer
提供以下配置选项:
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer<HttpSecurity> authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer<>();
http.apply(authorizationServerConfigurer);
authorizationServerConfigurer
.tokenIntrospectionEndpoint(tokenIntrospectionEndpoint ->
tokenIntrospectionEndpoint
.introspectionRequestConverter(introspectionRequestConverter) 【1】
.authenticationProvider(authenticationProvider) 【2】
.introspectionResponseHandler(introspectionResponseHandler) 【3】
.errorResponseHandler(errorResponseHandler) 【4】
);
return http.build();
}
1 |
|
2 |
|
3 |
|
4 |
|
OAuth2TokenIntrospectionEndpointConfigurer
配置OAuth2TokenIntrospectionEndpointFilter
并注册到 OAuth2 授权服务器SecurityFilterChain
@Bean
。 OAuth2TokenIntrospectionEndpointFilter
是Filter
处理 OAuth2 自省请求的。
OAuth2TokenIntrospectionEndpointFilter
配置有以下默认值:
**AuthenticationConverter**
— 一个返回OAuth2TokenIntrospectionAuthenticationToken
.**AuthenticationManager**
—AuthenticationManager
由 组成OAuth2TokenIntrospectionAuthenticationProvider
。**AuthenticationSuccessHandler**
— 处理“已验证”OAuth2TokenIntrospectionAuthenticationToken
并返回OAuth2TokenIntrospection
响应的内部实现。**AuthenticationFailureHandler**
— 使用与OAuth2Error
关联的内部实现OAuth2AuthenticationException
并返回OAuth2Error
响应。
OAuth2 令牌撤销端点
OAuth2TokenRevocationEndpointConfigurer
提供自定义OAuth2 令牌撤销端点的能力。它定义了扩展点,让您可以自定义OAuth2 撤销请求的预处理、主处理和后处理逻辑。
OAuth2TokenRevocationEndpointConfigurer
提供以下配置选项:
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer<HttpSecurity> authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer<>();
http.apply(authorizationServerConfigurer);
authorizationServerConfigurer
.tokenRevocationEndpoint(tokenRevocationEndpoint ->
tokenRevocationEndpoint
.revocationRequestConverter(revocationRequestConverter) 【1】
.authenticationProvider(authenticationProvider) 【2】
.revocationResponseHandler(revocationResponseHandler) 【3】
.errorResponseHandler(errorResponseHandler) 【4】
);
return http.build();
}
1 |
|
2 |
|
3 |
|
4 |
|
OAuth2TokenRevocationEndpointConfigurer
配置OAuth2TokenRevocationEndpointFilter
并注册到 OAuth2 授权服务器SecurityFilterChain
@Bean
。 OAuth2TokenRevocationEndpointFilter
是Filter
处理 OAuth2 撤销请求的。
OAuth2TokenRevocationEndpointFilter
配置有以下默认值:
**AuthenticationConverter**
— 一个返回OAuth2TokenRevocationAuthenticationToken
.**AuthenticationManager**
—AuthenticationManager
由 组成OAuth2TokenRevocationAuthenticationProvider
。**AuthenticationSuccessHandler**
— 处理“已验证”OAuth2TokenRevocationAuthenticationToken
并返回 OAuth2 撤销响应的内部实现。**AuthenticationFailureHandler**
— 使用与OAuth2Error
关联的内部实现OAuth2AuthenticationException
并返回OAuth2Error
响应。
OAuth2 授权服务器元数据端点
OAuth2AuthorizationServerConfigurer
提供对OAuth2 授权服务器元数据端点的支持。
OAuth2AuthorizationServerConfigurer
配置OAuth2AuthorizationServerMetadataEndpointFilter
并注册到 OAuth2 授权服务器SecurityFilterChain
@Bean
。 OAuth2AuthorizationServerMetadataEndpointFilter
是Filter
处理OAuth2 授权服务器元数据请求并返回OAuth2AuthorizationServerMetadata 响应的。
JWK 设置端点
OAuth2AuthorizationServerConfigurer
提供对JWK Set 端点的支持。
OAuth2AuthorizationServerConfigurer
配置NimbusJwkSetEndpointFilter
并注册到 OAuth2 授权服务器SecurityFilterChain
@Bean
。 NimbusJwkSetEndpointFilter
是Filter
返回JWK Set的。
OpenID Connect 1.0 提供者配置端点
OidcConfigurer
提供对OpenID Connect 1.0 Provider Configuration 端点的支持。
OidcConfigurer
配置OidcProviderConfigurationEndpointFilter
并注册到 OAuth2 授权服务器SecurityFilterChain
@Bean
。 OidcProviderConfigurationEndpointFilter
是Filter
返回OidcProviderConfiguration 响应的。
OpenID Connect 1.0 用户信息端点
OidcUserInfoEndpointConfigurer
提供定制OpenID Connect 1.0 UserInfo 端点的能力。它定义了允许您自定义UserInfo 响应的扩展点。
OidcUserInfoEndpointConfigurer
提供以下配置选项:
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer<HttpSecurity> authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer<>();
http.apply(authorizationServerConfigurer);
authorizationServerConfigurer
.oidc(oidc ->
oidc
.userInfoEndpoint(userInfoEndpoint ->
userInfoEndpoint.userInfoMapper(userInfoMapper)
)
);
return http.build();
}
OidcUserInfoEndpointConfigurer
配置OidcUserInfoEndpointFilter
并注册到 OAuth2 授权服务器SecurityFilterChain
@Bean
。 OidcUserInfoEndpointFilter
是Filter
处理UserInfo 请求并返回OidcUserInfo 响应的。
OidcUserInfoEndpointFilter
配置有以下默认值:
**AuthenticationManager**
—AuthenticationManager
由 组成,与根据授权期间请求的范围从ID 令牌中提取标准声明OidcUserInfoAuthenticationProvider
的内部实现相关联。userInfoMapper
OpenID Connect 1.0 UserInfo 端点是一个受 OAuth2 保护的资源,它需要一个访问令牌作为UserInfo 请求中的不记名令牌发送。以下示例显示如何启用 OAuth2 资源服务器配置:
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer<HttpSecurity> authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer<>();
http.apply(authorizationServerConfigurer);
...
http.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
return http.build();
}
@Bean
public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
}
OpenID Connect 1.0 客户端注册端点
OidcClientRegistrationEndpointConfigurer
配置OpenID Connect 1.0 客户端注册端点。以下示例显示如何启用(默认禁用)OpenID Connect 1.0 客户端注册端点:
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer<HttpSecurity> authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer<>();
http.apply(authorizationServerConfigurer);
authorizationServerConfigurer
.oidc(oidc ->
oidc
.clientRegistrationEndpoint(Customizer.withDefaults())
);
return http.build();
}
OidcClientRegistrationEndpointConfigurer
配置OidcClientRegistrationEndpointFilter
并注册到 OAuth2 授权服务器SecurityFilterChain
@Bean
。 OidcClientRegistrationEndpointFilter
是Filter
处理客户端注册请求并返回OidcClientRegistration 响应的。
OidcClientRegistrationEndpointFilter
配置有以下默认值:
**AuthenticationManager**
—AuthenticationManager
由 组成OidcClientRegistrationAuthenticationProvider
。
OpenID Connect 1.0 客户端注册端点是受 OAuth2 保护的资源,它需要一个访问令牌作为客户端注册(或客户端读取)请求中的不记名令牌发送。
以下示例显示如何启用 OAuth2 资源服务器配置:
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer<HttpSecurity> authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer<>();
http.apply(authorizationServerConfigurer);
...
http.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
return http.build();
}
@Bean
public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
}