Browse Source

Add Core Model / Components in ref doc

Closes gh-671
Joe Grandja 3 years ago
parent
commit
38e37ae3eb

+ 8 - 5
docs/src/docs/asciidoc/configuration-model.adoc

@@ -3,19 +3,22 @@
 :toc: left
 :toclevels: 1
 
-This page is under construction.
-
 [[oauth2-authorization-server-configurer]]
-== `OAuth2AuthorizationServerConfigurer`
+== OAuth2AuthorizationServerConfigurer
 
 This section is under construction.
 
 [[oauth2-authorization-server-configuration]]
-== `OAuth2AuthorizationServerConfiguration`
+== OAuth2AuthorizationServerConfiguration
 
 This section is under construction.
 
 [[provider-settings]]
-== `ProviderSettings` / `ProviderContext`
+== ProviderSettings
+
+This section is under construction.
+
+[[provider-context]]
+== ProviderContext
 
 This section is under construction.

+ 0 - 31
docs/src/docs/asciidoc/core-components.adoc

@@ -1,31 +0,0 @@
-[[core-components]]
-= Core Components
-:toc: left
-:toclevels: 1
-
-This page is under construction.
-
-[[registered-client-repository]]
-== `RegisteredClientRepository` / `RegisteredClient`
-
-This section is under construction.
-
-[[oauth2-authorization-service]]
-== `OAuth2AuthorizationService` / `OAuth2Authorization`
-
-This section is under construction.
-
-[[oauth2-authorization-consent-service]]
-== `OAuth2AuthorizationConsentService` / `OAuth2AuthorizationConsent`
-
-This section is under construction.
-
-[[jwt-encoder]]
-== `JwtEncoder`
-
-This section is under construction.
-
-[[oauth2-token-customizer]]
-== `OAuth2TokenCustomizer` / `OAuth2TokenContext`
-
-This section is under construction.

+ 477 - 0
docs/src/docs/asciidoc/core-model-components.adoc

@@ -0,0 +1,477 @@
+[[core-model-components]]
+= Core Model / Components
+:toc: left
+:toclevels: 1
+:spring-security-reference-base-url: https://docs.spring.io/spring-security/reference
+
+[[registered-client]]
+== RegisteredClient
+
+A `RegisteredClient` is a representation of a client that is https://datatracker.ietf.org/doc/html/rfc6749#section-2[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`.
+
+During client registration, the client is assigned a unique https://datatracker.ietf.org/doc/html/rfc6749#section-2.2[client identifier], (optionally) a client secret (depending on https://datatracker.ietf.org/doc/html/rfc6749#section-2.1[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).
+
+[TIP]
+The corresponding client registration model in Spring Security's OAuth2 Client support is {spring-security-reference-base-url}/servlet/oauth2/client/core.html#oauth2Client-client-registration[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.
+
+The following example shows how to configure a `RegisteredClient` that is allowed to perform the https://datatracker.ietf.org/doc/html/rfc6749#section-4.1[authorization_code grant] flow to request an access token:
+
+[source,java]
+----
+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 {spring-security-reference-base-url}/features/authentication/password-storage.html#authentication-password-storage-dpe[NoOpPasswordEncoder].
+
+The corresponding configuration in Spring Security's {spring-security-reference-base-url}/servlet/oauth2/client/index.html[OAuth2 Client support] is:
+
+[source,yaml]
+----
+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:
+
+[source,java]
+----
+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> `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 {spring-security-reference-base-url}/features/authentication/password-storage.html#authentication-password-storage-dpe[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`, https://datatracker.ietf.org/doc/html/rfc7523[`private_key_jwt`], `client_secret_jwt`, and `none` https://datatracker.ietf.org/doc/html/rfc7636[(public clients)].
+<8> `authorizationGrantTypes`: The https://datatracker.ietf.org/doc/html/rfc6749#section-1.3[authorization grant type(s)] that the client can use. The supported values are `authorization_code`, `client_credentials`, and `refresh_token`.
+<9> `redirectUris`: The registered https://datatracker.ietf.org/doc/html/rfc6749#section-3.1.2[redirect URI(s)] that the client may use in redirect-based flows – for example, `authorization_code` grant.
+<10> `scopes`: The scope(s) that the client is allowed to request.
+<11> `clientSettings`: The custom settings for the client – for example, require https://datatracker.ietf.org/doc/html/rfc7636[PKCE], require authorization consent, and others.
+<12> `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.
+
+[[registered-client-repository]]
+== 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.
+
+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`.
+
+[NOTE]
+The `RegisteredClientRepository` is a *REQUIRED* component.
+
+The following example shows how to register a `RegisteredClientRepository` `@Bean`:
+
+[source,java]
+----
+@Bean
+public RegisteredClientRepository registeredClientRepository() {
+	List<RegisteredClient> registrations = ...
+	return new InMemoryRegisteredClientRepository(registrations);
+}
+----
+
+Alternatively, you can configure the `RegisteredClientRepository` through the xref:configuration-model.adoc#oauth2-authorization-server-configurer[`OAuth2AuthorizationServerConfigurer`]:
+
+[source,java]
+----
+@Bean
+public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
+	OAuth2AuthorizationServerConfigurer<HttpSecurity> authorizationServerConfigurer =
+		new OAuth2AuthorizationServerConfigurer<>();
+	http.apply(authorizationServerConfigurer);
+
+	authorizationServerConfigurer
+		.registeredClientRepository(registeredClientRepository);
+
+	...
+
+	return http.build();
+}
+----
+
+[[oauth2-authorization]]
+== OAuth2Authorization
+
+An `OAuth2Authorization` is a representation of an OAuth2 authorization, which holds state related to the authorization granted to a <<registered-client, client>>, by the resource owner or itself in the case of the `client_credentials` authorization grant type.
+
+[TIP]
+The corresponding authorization model in Spring Security's OAuth2 Client support is {spring-security-reference-base-url}/servlet/oauth2/client/core.html#oauth2Client-authorized-client[OAuth2AuthorizedClient].
+
+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.
+
+The `OAuth2Token` instances associated with an `OAuth2Authorization` vary, depending on the authorization grant type.
+
+For the OAuth2 https://datatracker.ietf.org/doc/html/rfc6749#section-4.1[authorization_code grant], an `OAuth2AuthorizationCode`, an `OAuth2AccessToken`, and an (optional) `OAuth2RefreshToken` are associated.
+
+For the OpenID Connect 1.0 https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth[authorization_code grant], an `OAuth2AuthorizationCode`, an `OidcIdToken`, an `OAuth2AccessToken`, and an (optional) `OAuth2RefreshToken` are associated.
+
+For the OAuth2 https://datatracker.ietf.org/doc/html/rfc6749#section-4.4[client_credentials grant], only an `OAuth2AccessToken` is associated.
+
+`OAuth2Authorization` and its attributes are defined as follows:
+
+[source,java]
+----
+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> `id`: The ID that uniquely identifies the `OAuth2Authorization`.
+<2> `registeredClientId`: The ID that uniquely identifies the <<registered-client, RegisteredClient>>.
+<3> `principalName`: The principal name of the resource owner (or client).
+<4> `authorizationGrantType`: The `AuthorizationGrantType` used.
+<5> `tokens`: The `OAuth2Token` instances (and associated metadata) specific to the executed authorization grant type.
+<6> `attributes`: The additional attributes specific to the executed authorization grant type – for example, the authenticated `Principal`, `OAuth2AuthorizationRequest`, authorized scope(s), and others.
+
+`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` also provides `getClaims()`, which returns the claims (if any) associated with the `OAuth2Token`.
+
+[[oauth2-authorization-service]]
+== OAuth2AuthorizationService
+
+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.
+
+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`.
+
+[NOTE]
+The `OAuth2AuthorizationService` is an *OPTIONAL* component and defaults to `InMemoryOAuth2AuthorizationService`.
+
+The following example shows how to register an `OAuth2AuthorizationService` `@Bean`:
+
+[source,java]
+----
+@Bean
+public OAuth2AuthorizationService authorizationService() {
+	return new InMemoryOAuth2AuthorizationService();
+}
+----
+
+Alternatively, you can configure the `OAuth2AuthorizationService` through the xref:configuration-model.adoc#oauth2-authorization-server-configurer[`OAuth2AuthorizationServerConfigurer`]:
+
+[source,java]
+----
+@Bean
+public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
+	OAuth2AuthorizationServerConfigurer<HttpSecurity> authorizationServerConfigurer =
+		new OAuth2AuthorizationServerConfigurer<>();
+	http.apply(authorizationServerConfigurer);
+
+	authorizationServerConfigurer
+		.authorizationService(authorizationService);
+
+	...
+
+	return http.build();
+}
+----
+
+[[oauth2-authorization-consent]]
+== OAuth2AuthorizationConsent
+
+An `OAuth2AuthorizationConsent` is a representation of an authorization "consent" (decision) from an https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.1[OAuth2 authorization request flow] – for example, the `authorization_code` grant, which holds the authorities granted to a <<registered-client, client>> by the resource owner.
+
+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).
+
+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` and its attributes are defined as follows:
+
+[source,java]
+----
+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 <<registered-client, 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.
+
+[[oauth2-authorization-consent-service]]
+== OAuth2AuthorizationConsentService
+
+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.
+
+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`.
+
+[NOTE]
+The `OAuth2AuthorizationConsentService` is an *OPTIONAL* component and defaults to `InMemoryOAuth2AuthorizationConsentService`.
+
+The following example shows how to register an `OAuth2AuthorizationConsentService` `@Bean`:
+
+[source,java]
+----
+@Bean
+public OAuth2AuthorizationConsentService authorizationConsentService() {
+	return new InMemoryOAuth2AuthorizationConsentService();
+}
+----
+
+Alternatively, you can configure the `OAuth2AuthorizationConsentService` through the xref:configuration-model.adoc#oauth2-authorization-server-configurer[`OAuth2AuthorizationServerConfigurer`]:
+
+[source,java]
+----
+@Bean
+public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
+	OAuth2AuthorizationServerConfigurer<HttpSecurity> authorizationServerConfigurer =
+		new OAuth2AuthorizationServerConfigurer<>();
+	http.apply(authorizationServerConfigurer);
+
+	authorizationServerConfigurer
+		.authorizationConsentService(authorizationConsentService);
+
+	...
+
+	return http.build();
+}
+----
+
+[[oauth2-token-context]]
+== OAuth2TokenContext
+
+An `OAuth2TokenContext` is a context object that holds information associated with an `OAuth2Token` and is used by an <<oauth2-token-generator, OAuth2TokenGenerator>> and <<oauth2-token-customizer, OAuth2TokenCustomizer>>.
+
+`OAuth2TokenContext` provides the following accessors:
+
+[source,java]
+----
+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> `getRegisteredClient()`: The <<registered-client, RegisteredClient>> associated with the authorization grant.
+<2> `getPrincipal()`: The `Authentication` instance of the resource owner (or client).
+<3> `getProviderContext()`: The xref:configuration-model.adoc#provider-context[`ProviderContext`] object that holds information related to the provider.
+<4> `getAuthorization()`: The <<oauth2-authorization, 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`.
+<8> `getAuthorizationGrant()`: The `Authentication` instance used by the `AuthenticationProvider` that processes the authorization grant.
+
+[[oauth2-token-generator]]
+== OAuth2TokenGenerator
+
+An `OAuth2TokenGenerator` is responsible for generating an `OAuth2Token` from the information contained in the provided <<oauth2-token-context, OAuth2TokenContext>>.
+
+The `OAuth2Token` generated primarily depends on the type of `OAuth2TokenType` specified in the `OAuth2TokenContext`.
+
+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.
+
+Furthermore, the format of the generated `OAuth2AccessToken` varies, depending on the `TokenSettings.getAccessTokenFormat()` configured for the <<registered-client, 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.
+
+Finally, if the generated `OAuth2Token` has a set of claims and implements `ClaimAccessor`, the claims are made accessible from <<oauth2-authorization, OAuth2Authorization.Token.getClaims()>>.
+
+The `OAuth2TokenGenerator` is primarily used by components that implement authorization grant processing – for example, `authorization_code`, `client_credentials`, and `refresh_token`.
+
+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`).
+
+[NOTE]
+The `OAuth2TokenGenerator` is an *OPTIONAL* component and defaults to a `DelegatingOAuth2TokenGenerator` composed of an `OAuth2AccessTokenGenerator` and `OAuth2RefreshTokenGenerator`.
+As well, if a `JwtEncoder` `@Bean` or `JWKSource<SecurityContext>` `@Bean` is registered, then a `JwtGenerator` is additionally composed in the `DelegatingOAuth2TokenGenerator`.
+
+The `OAuth2TokenGenerator` provides great flexibility, as it can support any custom token format for `access_token` and `refresh_token`.
+
+The following example shows how to register an `OAuth2TokenGenerator` `@Bean`:
+
+[source,java]
+----
+@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);
+}
+----
+
+Alternatively, you can configure the `OAuth2TokenGenerator` through the xref:configuration-model.adoc#oauth2-authorization-server-configurer[`OAuth2AuthorizationServerConfigurer`]:
+
+[source,java]
+----
+@Bean
+public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
+	OAuth2AuthorizationServerConfigurer<HttpSecurity> authorizationServerConfigurer =
+		new OAuth2AuthorizationServerConfigurer<>();
+	http.apply(authorizationServerConfigurer);
+
+	authorizationServerConfigurer
+		.tokenGenerator(tokenGenerator);
+
+	...
+
+	return http.build();
+}
+----
+
+[[oauth2-token-customizer]]
+== OAuth2TokenCustomizer
+
+An `OAuth2TokenCustomizer` provides the ability to customize the attributes of an `OAuth2Token`, which are accessible in the provided <<oauth2-token-context, OAuth2TokenContext>>.
+It is used by an <<oauth2-token-generator, OAuth2TokenGenerator>> to let it customize the attributes of the `OAuth2Token` before it is generated.
+
+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.
+
+The following example shows how to implement an `OAuth2TokenCustomizer<OAuth2TokenClaimsContext>` and configure it with an `OAuth2AccessTokenGenerator`:
+
+[source,java]
+----
+@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
+
+	};
+}
+----
+
+[TIP]
+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`.
+
+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.getHeaders()` provides access to the `JoseHeader.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.
+
+The following example shows how to implement an `OAuth2TokenCustomizer<JwtEncodingContext>` and configure it with a `JwtGenerator`:
+
+[source,java]
+----
+@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 -> {
+		JoseHeader.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
+
+		}
+	};
+}
+----
+
+[TIP]
+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`.

+ 12 - 12
docs/src/docs/asciidoc/guides/how-to-jpa.adoc

@@ -9,19 +9,19 @@
 [[jpa-getting-started]]
 == Getting Started
 
-In this guide, we will demonstrate how to implement the xref:{docs-dir}/core-components.adoc#core-components[core services] of xref:{docs-dir}/index.adoc#top[Spring Authorization Server] with JPA. The purpose of this guide is to provide a starting point for implementing these services yourself, with the intention that you will make modifications as necessary to suit your needs.
+In this guide, we will demonstrate how to implement the xref:{docs-dir}/core-model-components.adoc#core-model-components[core services] of xref:{docs-dir}/index.adoc#top[Spring Authorization Server] with JPA. The purpose of this guide is to provide a starting point for implementing these services yourself, with the intention that you will make modifications as necessary to suit your needs.
 
 [[jpa-define-data-model]]
 == Define the data model
 
-This guide seeks to provide a starting point for the data model and uses the simplest possible structure and data types. To come up with the initial schema, we begin by reviewing the xref:{docs-dir}/core-components.adoc#core-components[domain objects] used by the core services. Please note:
+This guide seeks to provide a starting point for the data model and uses the simplest possible structure and data types. To come up with the initial schema, we begin by reviewing the xref:{docs-dir}/core-model-components.adoc#core-model-components[domain objects] used by the core services. Please note:
 
 NOTE: Except for token, state, metadata, settings and claims values, we will use the JPA default column length of 255 for all columns. In reality, the length and even type of columns you use may need to be customized. Your mileage may vary and you are encouraged to experiment and test before deploying to production.
 
 [[jpa-client-schema]]
 === Client Schema
 
-The xref:{docs-dir}/core-components.adoc#registered-client-repository[`RegisteredClient`] domain object contains a few multi-valued fields and some settings fields that require storing arbitrary key/value data. The following is an example that we will use to create a JPA entity.
+The xref:{docs-dir}/core-model-components.adoc#registered-client[`RegisteredClient`] domain object contains a few multi-valued fields and some settings fields that require storing arbitrary key/value data. The following is an example that we will use to create a JPA entity.
 
 .Client Schema
 [source,sql]
@@ -32,7 +32,7 @@ include::{examples-dir}/src/main/resources/oauth2-registered-client-schema.sql[]
 [[jpa-authorization-schema]]
 === Authorization Schema
 
-The xref:{docs-dir}/core-components.adoc#oauth2-authorization-service[`OAuth2Authorization`] domain object is more complex, and contains several multi-valued fields as well as numerous arbitrarily long token values, metadata, settings and claims values. The built-in JDBC implementation utilizes a flattened structure that prefers performance over normalization, which we adopt here as well.
+The xref:{docs-dir}/core-model-components.adoc#oauth2-authorization[`OAuth2Authorization`] domain object is more complex, and contains several multi-valued fields as well as numerous arbitrarily long token values, metadata, settings and claims values. The built-in JDBC implementation utilizes a flattened structure that prefers performance over normalization, which we adopt here as well.
 
 CAUTION: It has been difficult to find a flattened database schema that works well in all cases and with all database vendors. You may need to normalize or heavily alter the following schema for your needs.
 
@@ -47,7 +47,7 @@ include::{examples-dir}/src/main/resources/oauth2-authorization-schema.sql[]
 [[jpa-authorization-consent-schema]]
 === Authorization Consent Schema
 
-The xref:{docs-dir}/core-components.adoc#oauth2-authorization-consent-service[`OAuth2AuthorizationConsent`] domain object is the simplest to model, and only contains a single multi-valued field in addition to a composite key.  The following is an example that we will use to create a JPA entity.
+The xref:{docs-dir}/core-model-components.adoc#oauth2-authorization-consent[`OAuth2AuthorizationConsent`] domain object is the simplest to model, and only contains a single multi-valued field in addition to a composite key.  The following is an example that we will use to create a JPA entity.
 
 .Authorization Consent Schema
 [source,sql]
@@ -65,7 +65,7 @@ NOTE: The following entities are minimally annotated and are just examples. They
 [[jpa-client-entity]]
 === Client Entity
 
-The following is an example of the `Client` entity which is used to persist information mapped from the xref:{docs-dir}/core-components.adoc#registered-client-repository[`RegisteredClient`] domain object.
+The following is an example of the `Client` entity which is used to persist information mapped from the xref:{docs-dir}/core-model-components.adoc#registered-client[`RegisteredClient`] domain object.
 
 .Client Entity
 [source,java]
@@ -76,7 +76,7 @@ include::{examples-dir}/src/main/java/sample/jpa/Client.java[tag=class]
 [[jpa-authorization-entity]]
 === Authorization Entity
 
-The following is an example of the `Authorization` entity which is used to persist information mapped from the xref:{docs-dir}/core-components.adoc#oauth2-authorization-service[`OAuth2Authorization`] domain object.
+The following is an example of the `Authorization` entity which is used to persist information mapped from the xref:{docs-dir}/core-model-components.adoc#oauth2-authorization[`OAuth2Authorization`] domain object.
 
 .Authorization Entity
 [source,java]
@@ -87,7 +87,7 @@ include::{examples-dir}/src/main/java/sample/jpa/Authorization.java[tag=class]
 [[jpa-authorization-consent-entity]]
 === Authorization Consent Entity
 
-The following is an example of the `AuthorizationConsent` entity which is used to persist information mapped from the xref:{docs-dir}/core-components.adoc#oauth2-authorization-consent-service[`OAuth2AuthorizationConsent`] domain object.
+The following is an example of the `AuthorizationConsent` entity which is used to persist information mapped from the xref:{docs-dir}/core-model-components.adoc#oauth2-authorization-consent[`OAuth2AuthorizationConsent`] domain object.
 
 .Authorization Consent Entity
 [source,java]
@@ -143,7 +143,7 @@ CAUTION: Keep in mind that writing JSON data to text columns with a fixed length
 [[jpa-registered-client-repository]]
 === Registered Client Repository
 
-The following is an example of the `JpaRegisteredClientRepository` which uses a <<jpa-client-repository,`ClientRepository`>> for persisting a <<jpa-client-entity,`Client`>>, and maps to/from the xref:{docs-dir}/core-components.adoc#registered-client-repository[`RegisteredClient`] domain object.
+The following is an example of the `JpaRegisteredClientRepository` which uses a <<jpa-client-repository,`ClientRepository`>> for persisting a <<jpa-client-entity,`Client`>>, and maps to/from the xref:{docs-dir}/core-model-components.adoc#registered-client[`RegisteredClient`] domain object.
 
 .`RegisteredClientRepository` Implementation
 [source,java]
@@ -154,7 +154,7 @@ include::{examples-dir}/src/main/java/sample/jpa/JpaRegisteredClientRepository.j
 [[jpa-authorization-service]]
 === Authorization Service
 
-The following is an example of the `JpaOAuth2AuthorizationService` which uses an <<jpa-authorization-repository,`AuthorizationRepository`>> for persisting an <<jpa-authorization-entity,`Authorization`>>, and maps to/from the xref:{docs-dir}/core-components.adoc#oauth2-authorization-service[`OAuth2Authorization`] domain object.
+The following is an example of the `JpaOAuth2AuthorizationService` which uses an <<jpa-authorization-repository,`AuthorizationRepository`>> for persisting an <<jpa-authorization-entity,`Authorization`>>, and maps to/from the xref:{docs-dir}/core-model-components.adoc#oauth2-authorization[`OAuth2Authorization`] domain object.
 
 .`OAuth2AuthorizationService` Implementation
 [source,java]
@@ -165,10 +165,10 @@ include::{examples-dir}/src/main/java/sample/jpa/JpaOAuth2AuthorizationService.j
 [[jpa-authorization-consent-service]]
 === Authorization Consent Service
 
-The following is an example of the `JpaOAuth2AuthorizationConsentService` which uses an <<jpa-authorization-consent-repository,`AuthorizationConsentRepository`>> for persisting an <<jpa-authorization-consent-entity,`AuthorizationConsent`>>, and maps to/from the xref:{docs-dir}/core-components.adoc#oauth2-authorization-consent-service[`OAuth2AuthorizationConsent`] domain object.
+The following is an example of the `JpaOAuth2AuthorizationConsentService` which uses an <<jpa-authorization-consent-repository,`AuthorizationConsentRepository`>> for persisting an <<jpa-authorization-consent-entity,`AuthorizationConsent`>>, and maps to/from the xref:{docs-dir}/core-model-components.adoc#oauth2-authorization-consent[`OAuth2AuthorizationConsent`] domain object.
 
 .`OAuth2AuthorizationConsentService` Implementation
 [source,java]
 ----
 include::{examples-dir}/src/main/java/sample/jpa/JpaOAuth2AuthorizationConsentService.java[tag=class]
-----
+----

+ 1 - 1
docs/src/docs/asciidoc/index.adoc

@@ -8,7 +8,7 @@ xref:overview.adoc[Overview] :: Introduction and list of supported features
 xref:getting-help.adoc[Getting Help] :: Links to samples, questions and issues
 xref:getting-started.adoc[Getting Started] :: System requirements, dependencies and developing your first application
 xref:configuration-model.adoc[Configuration Model] :: Configuration and provider settings
-xref:core-components.adoc[Core Components] :: Domain objects and  service interfaces
+xref:core-model-components.adoc[Core Model / Components] :: Core domain model and component interfaces
 xref:protocol-endpoints.adoc[Protocol Endpoints] :: Specifications and endpoints
 xref:how-to.adoc["How-to" Guides] :: Guides to get the most from Spring Authorization Server
 xref:appendix.adoc[Appendices] :: Additional information