Core Model / Components

RegisteredClient

RegisteredClient 代表一个客户端,它与授权服务器 registered。在客户端可以发起授权授予流程(比如 authorization_codeclient_credentials)之前,它必须已在授权服务器上注册。

A RegisteredClient is a representation of a client that is registered with the authorization server. A client must be registered with the authorization server before it can initiate an authorization grant flow, such as authorization_code or client_credentials.

在客户端注册过程中,客户端将分配一个唯一的 client identifier,(可选的)客户端密码(取决于 client type)及与它的唯一客户端标识符相关联的元数据。该客户端的元数据可以从面向用户的显示字符串(比如客户端名称)到协议流程的特定项目(比如有效重定向 URI 的列表)。

During client registration, the client is assigned a unique client identifier, (optionally) a client secret (depending on client type), and metadata associated with its unique client identifier. The client’s metadata can range from human-facing display strings (such as client name) to items specific to a protocol flow (such as the list of valid redirect URIs).

Spring Security 的 OAuth2 客户端支持中对应的客户端注册模式为 ClientRegistration

The corresponding client registration model in Spring Security’s OAuth2 Client support is ClientRegistration.

客户端的主要目的是请求对受保护资源的访问。客户端首先通过使用授权服务器进行身份验证,并出示授权授予来请求访问令牌。授权服务器对客户端和授权授予进行身份验证;如果它们有效,则会颁发访问令牌。现在,客户端可以通过出示访问令牌向资源服务器请求受保护资源。

The primary purpose of a client is to request access to protected resources. The client first requests an access token by authenticating with the authorization server and presenting the authorization grant. The authorization server authenticates the client and authorization grant, and, if they are valid, issues an access token. The client can now request the protected resource from the resource server by presenting the access token.

以下示例展示了如何配置一个 RegisteredClient,它被允许执行 authorization_code grant 流程以请求访问令牌:

The following example shows how to configure a RegisteredClient that is allowed to perform the authorization_code grant flow to request an access token:

RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString())
	.clientId("client-a")
	.clientSecret("{noop}secret")   1
	.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();
1 {noop} represents the PasswordEncoder id for Spring Security’s NoOpPasswordEncoder.

Spring Security 的 OAuth2 Client 支持 中的相应配置为:

The corresponding configuration in Spring Security’s OAuth2 Client support is:

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

“已注册客户端”与其独特的客户端标识符关联有元数据(属性),定义如下:

A RegisteredClient has metadata (attributes) associated with its unique Client Identifier and is defined as follows:

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> postLogoutRedirectUris; 10
	private Set<String> scopes; 11
	private ClientSettings clientSettings;  12
	private TokenSettings tokenSettings;    13

	...

}
1 id: The ID that uniquely identifies the RegisteredClient.
2 clientId: The client identifier.
3 clientIdIssuedAt: The time at which the client identifier was issued.
4 clientSecret: The client’s secret. The value should be encoded using Spring Security’s PasswordEncoder.
5 clientSecretExpiresAt: The time at which the client secret expires.
6 clientName: A descriptive name used for the client. The name may be used in certain scenarios, such as when displaying the client name in the consent page.
7 clientAuthenticationMethods: The authentication method(s) that the client may use. The supported values are client_secret_basic, client_secret_post, private_key_jwt, client_secret_jwt, and none (public clients).
8 authorizationGrantTypes: The authorization grant type(s) that the client can use. The supported values are authorization_code, client_credentials, refresh_token, and urn:ietf:params:oauth:grant-type:device_code.
9 redirectUris: The registered redirect URI(s) that the client may use in redirect-based flows – for example, authorization_code grant.
10 postLogoutRedirectUris: The post logout redirect URI(s) that the client may use for logout.
11 scopes: The scope(s) that the client is allowed to request.
12 clientSettings: The custom settings for the client – for example, require PKCE, require authorization consent, and others.
13 tokenSettings: The custom settings for the OAuth2 tokens issued to the client – for example, access/refresh token time-to-live, reuse refresh tokens, and others.

RegisteredClientRepository

“已注册客户端存储库”是注册新客户端和查询现有客户端的中心组件。在关注特定的协议流(如客户端认证、授权授权处理、令牌自省、动态客户端注册等)时,其他组件会使用它。

The RegisteredClientRepository is the central component where new clients can be registered and existing clients can be queried. It is used by other components when following a specific protocol flow, such as client authentication, authorization grant processing, token introspection, dynamic client registration, and others.

提供的“已注册客户端存储库”实现有“内存中已注册客户端存储库”和“JDBC 已注册客户端存储库”。“内存中已注册客户端存储库”实现将“已注册客户端”实例存储在内存中,*仅*建议在开发和测试期间使用。“JDBC 已注册客户端存储库”是使用“JDBC 操作”来持久存储“已注册客户端”实例的 JDBC 实现。

The provided implementations of RegisteredClientRepository are InMemoryRegisteredClientRepository and JdbcRegisteredClientRepository. The InMemoryRegisteredClientRepository implementation stores RegisteredClient instances in-memory and is recommended ONLY to be used during development and testing. JdbcRegisteredClientRepository is a JDBC implementation that persists RegisteredClient instances by using JdbcOperations.

RegisteredClientRepositoryREQUIRED 组件。

The RegisteredClientRepository is a REQUIRED component.

下面的示例展示了如何注册一个“已注册客户端存储库”@Bean

The following example shows how to register a RegisteredClientRepository @Bean:

@Bean
public RegisteredClientRepository registeredClientRepository() {
	List<RegisteredClient> registrations = ...
	return new InMemoryRegisteredClientRepository(registrations);
}

或者,你可以通过 xref:configuration-model.adoc#customizing-the-configuration[OAuth2AuthorizationServerConfigurer 配置 RegisteredClientRepository

Alternatively, you can configure the RegisteredClientRepository through the OAuth2AuthorizationServerConfigurer:

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

	authorizationServerConfigurer
		.registeredClientRepository(registeredClientRepository);

	...

	return http.build();
}

当同时应用多个配置选项时,OAuth2AuthorizationServerConfigurer 很管用。

The OAuth2AuthorizationServerConfigurer is useful when applying multiple configuration options simultaneously.

OAuth2Authorization

OAuth2Authorization 是一个 OAuth2 授权的表示形式,其中包含与授权授予给 client 时所相关的状态,授权授予是资源所有者或在 client_credentials 授权授予类型的情况下本身授予的。

An OAuth2Authorization is a representation of an OAuth2 authorization, which holds state related to the authorization granted to a client, by the resource owner or itself in the case of the client_credentials authorization grant type.

Spring Security 的 OAuth2 客户端支持中对应的授权模型为 OAuth2AuthorizedClient

The corresponding authorization model in Spring Security’s OAuth2 Client support is OAuth2AuthorizedClient.

在成功完成授权授予流程后,将创建一个 OAuth2Authorization,并关联一个 OAuth2AccessToken,一个(可选的)https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/oauth2/core/OAuth2RefreshToken.html[OAuth2RefreshToken],以及执行授权授予类型的附加特定状态。

After the successful completion of an authorization grant flow, an OAuth2Authorization is created and associates an OAuth2AccessToken, an (optional) OAuth2RefreshToken, and additional state specific to the executed authorization grant type.

OAuth2Authorization 关联的 OAuth2Token 实例因授权授予类型而异。

The OAuth2Token instances associated with an OAuth2Authorization vary, depending on the authorization grant type.

对于 OAuth2 authorization_code grant,一个 OAuth2AuthorizationCode,一个 OAuth2AccessToken`和一个(可选的)`OAuth2RefreshToken 是相关的。

For the OAuth2 authorization_code grant, an OAuth2AuthorizationCode, an OAuth2AccessToken, and an (optional) OAuth2RefreshToken are associated.

对于 OpenID Connect 1.0 authorization_code grant,一个 OAuth2AuthorizationCode,一个 OidcIdToken,一个 OAuth2AccessToken,和一个(可选的)OAuth2RefreshToken 是相关的。

For the OpenID Connect 1.0 authorization_code grant, an OAuth2AuthorizationCode, an OidcIdToken, an OAuth2AccessToken, and an (optional) OAuth2RefreshToken are associated.

对于 OAuth2 client_credentials grant,仅一个 OAuth2AccessToken 是相关的。

For the OAuth2 client_credentials grant, only an OAuth2AccessToken is associated.

“OAuth2 授权”及其属性定义如下:

OAuth2Authorization and its attributes are defined as follows:

public class OAuth2Authorization implements Serializable {
	private String id;  1
	private String registeredClientId;  2
	private String principalName;   3
	private AuthorizationGrantType authorizationGrantType;  4
	private Set<String> authorizedScopes;   5
	private Map<Class<? extends OAuth2Token>, Token<?>> tokens; 6
	private Map<String, Object> attributes; 7

	...

}
1 id: The ID that uniquely identifies the OAuth2Authorization.
2 registeredClientId: The ID that uniquely identifies the RegisteredClient.
3 principalName: The principal name of the resource owner (or client).
4 authorizationGrantType: The AuthorizationGrantType used.
5 authorizedScopes: The Set of scope(s) authorized for the client.
6 tokens: The OAuth2Token instances (and associated metadata) specific to the executed authorization grant type.
7 attributes: The additional attributes specific to the executed authorization grant type – for example, the authenticated Principal, OAuth2AuthorizationRequest, and others.

“OAuth2 授权”及其关联的 OAuth2Token 实例具有一个设置的生存期。新颁发的 OAuth2Token 是处于活动状态的,当它过期或无效(被吊销)时,会变成非活动状态。“OAuth2 授权”在所有关联的 OAuth2Token 实例均为非活动状态时(隐式地)为非活动状态。每个 OAuth2Token 都保存在一个 OAuth2Authorization.Token 中,其中提供对 isExpired()isInvalidated()isActive() 的访问器。

OAuth2Authorization and its associated OAuth2Token instances have a set lifespan. A newly issued OAuth2Token is active and becomes inactive when it either expires or is invalidated (revoked). The OAuth2Authorization is (implicitly) inactive when all associated OAuth2Token instances are inactive. Each OAuth2Token is held in an OAuth2Authorization.Token, which provides accessors for isExpired(), isInvalidated(), and isActive().

OAuth2Authorization.Token 还提供 getClaims(),用于返回与 OAuth2Token 关联的声明(如果存在)。

OAuth2Authorization.Token also provides getClaims(), which returns the claims (if any) associated with the OAuth2Token.

OAuth2AuthorizationService

“OAuth2 授权服务”是存储新授权和查询现有授权的中心组件。在关注特定的协议流时,其他组件会使用它 – 例如,客户端认证、授权授权处理、令牌自省、令牌吊销、动态客户端注册等。

The OAuth2AuthorizationService is the central component where new authorizations are stored and existing authorizations are queried. It is used by other components when following a specific protocol flow – for example, client authentication, authorization grant processing, token introspection, token revocation, dynamic client registration, and others.

提供的“OAuth2 授权服务”实现有“内存中 OAuth2 授权服务”和“JDBC OAuth2 授权服务”。“内存中 OAuth2 授权服务”实现将“OAuth2 授权”实例存储在内存中,*仅*建议在开发和测试期间使用。“JDBC OAuth2 授权服务”是使用“JDBC 操作”来持久存储“OAuth2 授权”实例的 JDBC 实现。

The provided implementations of OAuth2AuthorizationService are InMemoryOAuth2AuthorizationService and JdbcOAuth2AuthorizationService. The InMemoryOAuth2AuthorizationService implementation stores OAuth2Authorization instances in-memory and is recommended ONLY to be used during development and testing. JdbcOAuth2AuthorizationService is a JDBC implementation that persists OAuth2Authorization instances by using JdbcOperations.

OAuth2AuthorizationServiceOPTIONAL 组件,默认为 InMemoryOAuth2AuthorizationService

The OAuth2AuthorizationService is an OPTIONAL component and defaults to InMemoryOAuth2AuthorizationService.

下面的示例展示了如何注册一个“OAuth2 授权服务”@Bean

The following example shows how to register an OAuth2AuthorizationService @Bean:

@Bean
public OAuth2AuthorizationService authorizationService() {
	return new InMemoryOAuth2AuthorizationService();
}

或者,你可以通过 xref:configuration-model.adoc#customizing-the-configuration[OAuth2AuthorizationServerConfigurer 配置 OAuth2AuthorizationService

Alternatively, you can configure the OAuth2AuthorizationService through the OAuth2AuthorizationServerConfigurer:

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

	authorizationServerConfigurer
		.authorizationService(authorizationService);

	...

	return http.build();
}

当同时应用多个配置选项时,OAuth2AuthorizationServerConfigurer 很管用。

The OAuth2AuthorizationServerConfigurer is useful when applying multiple configuration options simultaneously.

一个 OAuth2AuthorizationConsent 代表一个 OAuth2 authorization request flow(例如保持 authorities 授予给 client 的资源所有者的 authorization_code)授予的授权“同意”(决策)。

An OAuth2AuthorizationConsent is a representation of an authorization "consent" (decision) from an OAuth2 authorization request flow – for example, the authorization_code grant, which holds the authorities granted to a client by the resource owner.

在授权对客户端的访问权限时,资源所有者可以只授予客户端请求的权限中的一个子集。典型的用例是 authorization_code 授权流,其中客户端请求范围,资源所有者授予(或拒绝)对请求的范围的访问权限。

When authorizing access to a client, the resource owner may grant only a subset of the authorities requested by the client. The typical use case is the authorization_code grant flow, in which the client requests scope(s) and the resource owner grants (or denies) access to the requested scope(s).

在 OAuth2 授权请求流完成后,将创建一个(或更新)OAuth2AuthorizationConsent,并将已授予的权限与客户端和资源所有者关联。

After the completion of an OAuth2 authorization request flow, an OAuth2AuthorizationConsent is created (or updated) and associates the granted authorities with the client and resource owner.

OAuth2AuthorizationConsent 及其属性定义如下:

OAuth2AuthorizationConsent and its attributes are defined as follows:

public final class OAuth2AuthorizationConsent implements Serializable {
	private final String registeredClientId;    1
	private final String principalName; 2
	private final Set<GrantedAuthority> authorities;    3

	...

}
1 registeredClientId: The ID that uniquely identifies the RegisteredClient.
2 principalName: The principal name of the resource owner.
3 authorities: The authorities granted to the client by the resource owner. An authority can represent a scope, a claim, a permission, a role, and others.

OAuth2AuthorizationConsentService 是存储新授权同意并查询现有授权同意的中心组件。它主要用于实现 OAuth2 授权请求流的组件,例如 authorization_code 授权。

The OAuth2AuthorizationConsentService is the central component where new authorization consents are stored and existing authorization consents are queried. It is primarily used by components that implement an OAuth2 authorization request flow – for example, the authorization_code grant.

OAuth2AuthorizationConsentService 提供的实现有 InMemoryOAuth2AuthorizationConsentServiceJdbcOAuth2AuthorizationConsentServiceInMemoryOAuth2AuthorizationConsentService 实现将 OAuth2AuthorizationConsent 实例存储在内存中,*仅*建议在开发和测试中使用。JdbcOAuth2AuthorizationConsentService 是一种 JDBC 实现,它使用 JdbcOperations 来持久存储 OAuth2AuthorizationConsent 实例。

The provided implementations of OAuth2AuthorizationConsentService are InMemoryOAuth2AuthorizationConsentService and JdbcOAuth2AuthorizationConsentService. The InMemoryOAuth2AuthorizationConsentService implementation stores OAuth2AuthorizationConsent instances in-memory and is recommended ONLY for development and testing. JdbcOAuth2AuthorizationConsentService is a JDBC implementation that persists OAuth2AuthorizationConsent instances by using JdbcOperations.

OAuth2AuthorizationConsentServiceOPTIONAL 组件,默认为 InMemoryOAuth2AuthorizationConsentService

The OAuth2AuthorizationConsentService is an OPTIONAL component and defaults to InMemoryOAuth2AuthorizationConsentService.

以下示例展示了如何注册 OAuth2AuthorizationConsentService @Bean

The following example shows how to register an OAuth2AuthorizationConsentService @Bean:

@Bean
public OAuth2AuthorizationConsentService authorizationConsentService() {
	return new InMemoryOAuth2AuthorizationConsentService();
}

或者,你可以通过 xref:configuration-model.adoc#customizing-the-configuration[OAuth2AuthorizationServerConfigurer 配置 OAuth2AuthorizationConsentService

Alternatively, you can configure the OAuth2AuthorizationConsentService through the OAuth2AuthorizationServerConfigurer:

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

	authorizationServerConfigurer
		.authorizationConsentService(authorizationConsentService);

	...

	return http.build();
}

当同时应用多个配置选项时,OAuth2AuthorizationServerConfigurer 很管用。

The OAuth2AuthorizationServerConfigurer is useful when applying multiple configuration options simultaneously.

OAuth2TokenContext

OAuth2TokenContext 是一个持有与 OAuth2Token 相关的信息的环境对象,其被 OAuth2TokenGeneratorOAuth2TokenCustomizer 使用。

An OAuth2TokenContext is a context object that holds information associated with an OAuth2Token and is used by an OAuth2TokenGenerator and OAuth2TokenCustomizer.

OAuth2TokenContext 提供以下访问器:

OAuth2TokenContext provides the following accessors:

public interface OAuth2TokenContext extends Context {

	default RegisteredClient getRegisteredClient() ...  1

	default <T extends Authentication> T getPrincipal() ... 2

	default AuthorizationServerContext getAuthorizationServerContext() ...    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 getRegisteredClient(): The RegisteredClient associated with the authorization grant.
2 getPrincipal(): The Authentication instance of the resource owner (or client).
3 getAuthorizationServerContext(): The AuthorizationServerContext object that holds information of the Authorization Server runtime environment.
4 getAuthorization(): The OAuth2Authorization associated with the authorization grant.
5 getAuthorizedScopes(): The scope(s) authorized for the client.
6 getTokenType(): The OAuth2TokenType to generate. The supported values are code, access_token, refresh_token, and id_token.
7 getAuthorizationGrantType(): The AuthorizationGrantType associated with the authorization grant.
8 getAuthorizationGrant(): The Authentication instance used by the AuthenticationProvider that processes the authorization grant.

OAuth2TokenGenerator

OAuth2TokenGenerator 负责根据所提供的 OAuth2TokenContext 中包含的信息来生成 OAuth2Token

An OAuth2TokenGenerator is responsible for generating an OAuth2Token from the information contained in the provided OAuth2TokenContext.

生成的 OAuth2Token 主要取决于 OAuth2TokenContext 中指定的 OAuth2TokenType 类型。

The OAuth2Token generated primarily depends on the type of OAuth2TokenType specified in the OAuth2TokenContext.

例如,当 OAuth2TokenTypevalue 为:

For example, when the value for OAuth2TokenType is:

  • code, then OAuth2AuthorizationCode is generated.

  • access_token, then OAuth2AccessToken is generated.

  • refresh_token, then OAuth2RefreshToken is generated.

  • id_token, then OidcIdToken is generated.

此外,所生成 OAuth2AccessToken 的格式取决于为 RegisteredClient 配置的 TokenSettings.getAccessTokenFormat()。如果格式是 OAuth2TokenFormat.SELF_CONTAINED (默认),则将生成 Jwt。如果格式是 OAuth2TokenFormat.REFERENCE,则将生成一个“不透明”令牌。

Furthermore, the format of the generated OAuth2AccessToken varies, depending on the TokenSettings.getAccessTokenFormat() configured for the RegisteredClient. If the format is OAuth2TokenFormat.SELF_CONTAINED (the default), then a Jwt is generated. If the format is OAuth2TokenFormat.REFERENCE, then an "opaque" token is generated.

最后,如果所生成的 OAuth2Token 有一组声明并且实现了 ClaimAccessor,声明可以从 OAuth2Authorization.Token.getClaims() 访问。

Finally, if the generated OAuth2Token has a set of claims and implements ClaimAccessor, the claims are made accessible from OAuth2Authorization.Token.getClaims().

OAuth2TokenGenerator 主要被实现授权授予流程的组件使用,例如 authorization_codeclient_credentialsrefresh_token

The OAuth2TokenGenerator is primarily used by components that implement authorization grant processing – for example, authorization_code, client_credentials, and refresh_token.

提供的实现有 OAuth2AccessTokenGeneratorOAuth2RefreshTokenGeneratorJwtGeneratorOAuth2AccessTokenGenerator 生成一个“不透明”(OAuth2TokenFormat.REFERENCE)访问令牌,而 JwtGenerator 生成一个 Jwt (OAuth2TokenFormat.SELF_CONTAINED)。

The provided implementations are OAuth2AccessTokenGenerator, OAuth2RefreshTokenGenerator, and JwtGenerator. The OAuth2AccessTokenGenerator generates an "opaque" (OAuth2TokenFormat.REFERENCE) access token, and the JwtGenerator generates a Jwt (OAuth2TokenFormat.SELF_CONTAINED).

OAuth2TokenGeneratorOPTIONAL 组件,默认为由 OAuth2AccessTokenGeneratorOAuth2RefreshTokenGenerator 组成的 DelegatingOAuth2TokenGenerator

The OAuth2TokenGenerator is an OPTIONAL component and defaults to a DelegatingOAuth2TokenGenerator composed of an OAuth2AccessTokenGenerator and OAuth2RefreshTokenGenerator.

如果注册了 JwtEncoder @BeanJWKSource<SecurityContext> @Bean,则会另外在 DelegatingOAuth2TokenGenerator 中组成一个 JwtGenerator

If a JwtEncoder @Bean or JWKSource<SecurityContext> @Bean is registered, then a JwtGenerator is additionally composed in the DelegatingOAuth2TokenGenerator.

OAuth2TokenGenerator 提供了很大的灵活性,因为它可以支持 access_tokenrefresh_token 的任何自定义令牌格式。

The OAuth2TokenGenerator provides great flexibility, as it can support any custom token format for access_token and refresh_token.

以下示例展示了如何注册一个 OAuth2TokenGenerator @Bean

The following example shows how to register an 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);
}

或者,你可以通过 xref:configuration-model.adoc#customizing-the-configuration[OAuth2AuthorizationServerConfigurer 配置 OAuth2TokenGenerator

Alternatively, you can configure the OAuth2TokenGenerator through the OAuth2AuthorizationServerConfigurer:

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

	authorizationServerConfigurer
		.tokenGenerator(tokenGenerator);

	...

	return http.build();
}

当同时应用多个配置选项时,OAuth2AuthorizationServerConfigurer 很管用。

The OAuth2AuthorizationServerConfigurer is useful when applying multiple configuration options simultaneously.

OAuth2TokenCustomizer

OAuth2TokenCustomizer 提供自定义 OAuth2Token 属性的能力,该属性可以在所提供的 OAuth2TokenContext 中访问。它被 OAuth2TokenGenerator 用于在生成 OAuth2Token 之前自定义它的属性。

An OAuth2TokenCustomizer provides the ability to customize the attributes of an OAuth2Token, which are accessible in the provided OAuth2TokenContext. It is used by an OAuth2TokenGenerator to let it customize the attributes of the OAuth2Token before it is generated.

声明为泛型类型为 OAuth2TokenClaimsContextimplements OAuth2TokenContext)的 OAuth2TokenCustomizer<OAuth2TokenClaimsContext> 提供了自定义一个“不透明” OAuth2AccessToken 的声明的能力。OAuth2TokenClaimsContext.getClaims() 提供对 OAuth2TokenClaimsSet.Builder 的访问,允许添加、替换和删除声明。

An OAuth2TokenCustomizer<OAuth2TokenClaimsContext> declared with a generic type of OAuth2TokenClaimsContext (implements OAuth2TokenContext) provides the ability to customize the claims of an "opaque" OAuth2AccessToken. OAuth2TokenClaimsContext.getClaims() provides access to the OAuth2TokenClaimsSet.Builder, allowing the ability to add, replace, and remove claims.

以下示例演示如何实现 OAuth2TokenCustomizer<OAuth2TokenClaimsContext>,并使用 OAuth2AccessTokenGenerator 对其进行配置:

The following example shows how to implement an OAuth2TokenCustomizer<OAuth2TokenClaimsContext> and configure it with an 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

	};
}

如果没有将 OAuth2TokenGenerator 提供为 @Bean 或者未通过 OAuth2AuthorizationServerConfigurer 配置,则会自动配置一个 OAuth2TokenCustomizer<OAuth2TokenClaimsContext> @Bean,并使用 OAuth2AccessTokenGenerator

If the OAuth2TokenGenerator is not provided as a @Bean or is not configured through the OAuth2AuthorizationServerConfigurer, an OAuth2TokenCustomizer<OAuth2TokenClaimsContext> @Bean will automatically be configured with an OAuth2AccessTokenGenerator.

声明为通用类型 JwtEncodingContext(实施 OAuth2TokenContext)的 OAuth2TokenCustomizer<JwtEncodingContext> 提供了定制 Jwt 的标头和声明的功能。JwtEncodingContext.getJwsHeader() 提供了对 JwsHeader.Builder 的访问,可以使用该访问添加、替换和删除标头。JwtEncodingContext.getClaims() 提供了对 JwtClaimsSet.Builder 的访问,可以使用该访问添加、替换和删除声明。

An OAuth2TokenCustomizer<JwtEncodingContext> declared with a generic type of JwtEncodingContext (implements OAuth2TokenContext) provides the ability to customize the headers and claims of a Jwt. JwtEncodingContext.getJwsHeader() provides access to the JwsHeader.Builder, allowing the ability to add, replace, and remove headers. JwtEncodingContext.getClaims() provides access to the JwtClaimsSet.Builder, allowing the ability to add, replace, and remove claims.

以下示例演示如何实现 OAuth2TokenCustomizer<JwtEncodingContext>,并使用 JwtGenerator 对其进行配置:

The following example shows how to implement an OAuth2TokenCustomizer<JwtEncodingContext> and configure it with 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.getJwsHeader();
		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

		}
	};
}

如果没有将 OAuth2TokenGenerator 提供为 @Bean 或者未通过 OAuth2AuthorizationServerConfigurer 配置,则会自动配置一个 OAuth2TokenCustomizer<JwtEncodingContext> @Bean,并使用 JwtGenerator

If the OAuth2TokenGenerator is not provided as a @Bean or is not configured through the OAuth2AuthorizationServerConfigurer, an OAuth2TokenCustomizer<JwtEncodingContext> @Bean will automatically be configured with a JwtGenerator.

For an example showing how you can customize the ID token, see the guide How-to: Customize the OpenID Connect 1.0 UserInfo response.

SessionRegistry

如果启用 OpenID Connect 1.0,一个 SessionRegistry 实例将用于跟踪已验证的会话。SessionRegistryOAuth2 Authorization Endpoint 关联的 SessionAuthenticationStrategy 的默认实现用来注册新的已验证的会话。

If OpenID Connect 1.0 is enabled, a SessionRegistry instance is used to track authenticated sessions. The SessionRegistry is used by the default implementation of SessionAuthenticationStrategy associated to the OAuth2 Authorization Endpoint for registering new authenticated sessions.

如果未注册 SessionRegistry @Bean,则将使用默认实现 SessionRegistryImpl

If a SessionRegistry @Bean is not registered, the default implementation SessionRegistryImpl will be used.

如果一个 SessionRegistry @Bean 已注册并且是 SessionRegistryImpl 的一个实例,那么一个 HttpSessionEventPublisher @Bean SHOULD 也可注册为它负责通知 SessionRegistryImpl 会话生命周期事件,例如 SessionDestroyedEvent,以提供删除 SessionInformation 实例的能力。

If a SessionRegistry @Bean is registered and is an instance of SessionRegistryImpl, a HttpSessionEventPublisher @Bean SHOULD also be registered as it’s responsible for notifying SessionRegistryImpl of session lifecycle events, for example, SessionDestroyedEvent, to provide the ability to remove the SessionInformation instance.

当注销是由终端用户请求时,OpenID Connect 1.0 Logout Endpoint 使用 SessionRegistry 来查找与已验证的终端用户关联的 SessionInformation 以执行注销。

When a logout is requested by an End-User, the OpenID Connect 1.0 Logout Endpoint uses the SessionRegistry to lookup the SessionInformation associated to the authenticated End-User to perform the logout.

如果正在使用 Spring Security 的 并发会话控制 功能,则它是 *RECOMMENDED*注册 SessionRegistry @Bean,以确保它在 Spring Security 的并发会话控制和 Spring Authorization Server 的注销功能之间共享。

If Spring Security’s Concurrent Session Control feature is being used, it is RECOMMENDED to register a SessionRegistry @Bean to ensure it’s shared between Spring Security’s Concurrent Session Control and Spring Authorization Server’s Logout feature.

以下示例演示如何注册 SessionRegistry @BeanHttpSessionEventPublisher @BeanSessionRegistryImpl 所需):

The following example shows how to register a SessionRegistry @Bean and HttpSessionEventPublisher @Bean (required by SessionRegistryImpl):

@Bean
public SessionRegistry sessionRegistry() {
	return new SessionRegistryImpl();
}

@Bean
public HttpSessionEventPublisher httpSessionEventPublisher() {
	return new HttpSessionEventPublisher();
}