Manual move of spring-projects/spring-authorization-server docs
Issue gh-17880
This commit is contained in:
@@ -0,0 +1,430 @@
|
||||
[[configuration-model]]
|
||||
= Configuration Model
|
||||
|
||||
[[default-configuration]]
|
||||
== Default configuration
|
||||
|
||||
`OAuth2AuthorizationServerConfiguration` is a `@Configuration` that provides the minimal default configuration for an OAuth2 authorization server.
|
||||
|
||||
`OAuth2AuthorizationServerConfiguration` uses xref:configuration-model.adoc#customizing-the-configuration[`OAuth2AuthorizationServerConfigurer`] to apply the default configuration and registers a `SecurityFilterChain` `@Bean` composed of all the infrastructure components supporting an OAuth2 authorization server.
|
||||
|
||||
The OAuth2 authorization server `SecurityFilterChain` `@Bean` is configured with the following default protocol endpoints:
|
||||
|
||||
* xref:protocol-endpoints.adoc#oauth2-authorization-endpoint[OAuth2 Authorization endpoint]
|
||||
* xref:protocol-endpoints.adoc#oauth2-device-authorization-endpoint[OAuth2 Device Authorization Endpoint]
|
||||
* xref:protocol-endpoints.adoc#oauth2-device-verification-endpoint[OAuth2 Device Verification Endpoint]
|
||||
* xref:protocol-endpoints.adoc#oauth2-token-endpoint[OAuth2 Token endpoint]
|
||||
* xref:protocol-endpoints.adoc#oauth2-token-introspection-endpoint[OAuth2 Token Introspection endpoint]
|
||||
* xref:protocol-endpoints.adoc#oauth2-token-revocation-endpoint[OAuth2 Token Revocation endpoint]
|
||||
* xref:protocol-endpoints.adoc#oauth2-authorization-server-metadata-endpoint[OAuth2 Authorization Server Metadata endpoint]
|
||||
* xref:protocol-endpoints.adoc#jwk-set-endpoint[JWK Set endpoint]
|
||||
|
||||
[NOTE]
|
||||
The JWK Set endpoint is configured *only* if a `JWKSource<SecurityContext>` `@Bean` is registered.
|
||||
|
||||
The following example shows how to use `OAuth2AuthorizationServerConfiguration` to apply the minimal default configuration:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@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);
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
[IMPORTANT]
|
||||
The https://datatracker.ietf.org/doc/html/rfc6749#section-4.1[authorization_code grant] requires the resource owner to be authenticated. Therefore, a user authentication mechanism *must* be configured in addition to the default OAuth2 security configuration.
|
||||
|
||||
https://openid.net/specs/openid-connect-core-1_0.html[OpenID Connect 1.0] is disabled in the default configuration. The following example shows how to enable OpenID Connect 1.0 by initializing the `OidcConfigurer`:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
|
||||
OAuth2AuthorizationServerConfigurer.authorizationServer();
|
||||
http
|
||||
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
|
||||
.with(authorizationServerConfigurer, (authorizationServer) ->
|
||||
authorizationServer
|
||||
.oidc(Customizer.withDefaults()) // Initialize `OidcConfigurer`
|
||||
);
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
|
||||
In addition to the default protocol endpoints, the OAuth2 authorization server `SecurityFilterChain` `@Bean` is configured with the following OpenID Connect 1.0 protocol endpoints:
|
||||
|
||||
* xref:protocol-endpoints.adoc#oidc-provider-configuration-endpoint[OpenID Connect 1.0 Provider Configuration endpoint]
|
||||
* xref:protocol-endpoints.adoc#oidc-logout-endpoint[OpenID Connect 1.0 Logout endpoint]
|
||||
* xref:protocol-endpoints.adoc#oidc-user-info-endpoint[OpenID Connect 1.0 UserInfo endpoint]
|
||||
|
||||
[NOTE]
|
||||
The xref:protocol-endpoints.adoc#oidc-client-registration-endpoint[OpenID Connect 1.0 Client Registration endpoint] is disabled by default because many deployments do not require dynamic client registration.
|
||||
|
||||
[TIP]
|
||||
`OAuth2AuthorizationServerConfiguration.jwtDecoder(JWKSource<SecurityContext>)` is a convenience (`static`) utility method that can be used to register a `JwtDecoder` `@Bean`, which is *REQUIRED* for the xref:protocol-endpoints.adoc#oidc-user-info-endpoint[OpenID Connect 1.0 UserInfo endpoint] and the xref:protocol-endpoints.adoc#oidc-client-registration-endpoint[OpenID Connect 1.0 Client Registration endpoint].
|
||||
|
||||
The following example shows how to register a `JwtDecoder` `@Bean`:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
|
||||
return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
|
||||
}
|
||||
----
|
||||
|
||||
The main intent of `OAuth2AuthorizationServerConfiguration` is to provide a convenient method to apply the minimal default configuration for an OAuth2 authorization server. However, in most cases, customizing the configuration will be required.
|
||||
|
||||
[[customizing-the-configuration]]
|
||||
== Customizing the configuration
|
||||
|
||||
`OAuth2AuthorizationServerConfigurer` provides the ability to fully customize the security configuration for an OAuth2 authorization server.
|
||||
It lets you specify the core components to use - for example, xref:core-model-components.adoc#registered-client-repository[`RegisteredClientRepository`], xref:core-model-components.adoc#oauth2-authorization-service[`OAuth2AuthorizationService`], xref:core-model-components.adoc#oauth2-token-generator[`OAuth2TokenGenerator`], and others.
|
||||
Furthermore, it lets you customize the request processing logic for the protocol endpoints – for example, xref:protocol-endpoints.adoc#oauth2-authorization-endpoint[authorization endpoint], xref:protocol-endpoints.adoc#oauth2-device-authorization-endpoint[device authorization endpoint], xref:protocol-endpoints.adoc#oauth2-device-verification-endpoint[device verification endpoint], xref:protocol-endpoints.adoc#oauth2-token-endpoint[token endpoint], xref:protocol-endpoints.adoc#oauth2-token-introspection-endpoint[token introspection endpoint], and others.
|
||||
|
||||
`OAuth2AuthorizationServerConfigurer` provides the following configuration options:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
|
||||
OAuth2AuthorizationServerConfigurer.authorizationServer();
|
||||
|
||||
http
|
||||
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
|
||||
.with(authorizationServerConfigurer, (authorizationServer) ->
|
||||
authorizationServer
|
||||
.registeredClientRepository(registeredClientRepository) <1>
|
||||
.authorizationService(authorizationService) <2>
|
||||
.authorizationConsentService(authorizationConsentService) <3>
|
||||
.authorizationServerSettings(authorizationServerSettings) <4>
|
||||
.tokenGenerator(tokenGenerator) <5>
|
||||
.clientAuthentication(clientAuthentication -> { }) <6>
|
||||
.authorizationEndpoint(authorizationEndpoint -> { }) <7>
|
||||
.pushedAuthorizationRequestEndpoint(pushedAuthorizationRequestEndpoint -> { }) <8>
|
||||
.deviceAuthorizationEndpoint(deviceAuthorizationEndpoint -> { }) <9>
|
||||
.deviceVerificationEndpoint(deviceVerificationEndpoint -> { }) <10>
|
||||
.tokenEndpoint(tokenEndpoint -> { }) <11>
|
||||
.tokenIntrospectionEndpoint(tokenIntrospectionEndpoint -> { }) <12>
|
||||
.tokenRevocationEndpoint(tokenRevocationEndpoint -> { }) <13>
|
||||
.authorizationServerMetadataEndpoint(authorizationServerMetadataEndpoint -> { }) <14>
|
||||
.oidc(oidc -> oidc
|
||||
.providerConfigurationEndpoint(providerConfigurationEndpoint -> { }) <15>
|
||||
.logoutEndpoint(logoutEndpoint -> { }) <16>
|
||||
.userInfoEndpoint(userInfoEndpoint -> { }) <17>
|
||||
.clientRegistrationEndpoint(clientRegistrationEndpoint -> { }) <18>
|
||||
)
|
||||
);
|
||||
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
<1> `registeredClientRepository()`: The xref:core-model-components.adoc#registered-client-repository[`RegisteredClientRepository`] (*REQUIRED*) for managing new and existing clients.
|
||||
<2> `authorizationService()`: The xref:core-model-components.adoc#oauth2-authorization-service[`OAuth2AuthorizationService`] for managing new and existing authorizations.
|
||||
<3> `authorizationConsentService()`: The xref:core-model-components.adoc#oauth2-authorization-consent-service[`OAuth2AuthorizationConsentService`] for managing new and existing authorization consents.
|
||||
<4> `authorizationServerSettings()`: The xref:configuration-model.adoc#configuring-authorization-server-settings[`AuthorizationServerSettings`] (*REQUIRED*) for customizing configuration settings for the OAuth2 authorization server.
|
||||
<5> `tokenGenerator()`: The xref:core-model-components.adoc#oauth2-token-generator[`OAuth2TokenGenerator`] for generating tokens supported by the OAuth2 authorization server.
|
||||
<6> `clientAuthentication()`: The configurer for xref:configuration-model.adoc#configuring-client-authentication[OAuth2 Client Authentication].
|
||||
<7> `authorizationEndpoint()`: The configurer for the xref:protocol-endpoints.adoc#oauth2-authorization-endpoint[OAuth2 Authorization endpoint].
|
||||
<8> `pushedAuthorizationRequestEndpoint()`: The configurer for the xref:protocol-endpoints.adoc#oauth2-pushed-authorization-request-endpoint[OAuth2 Pushed Authorization Request endpoint].
|
||||
<9> `deviceAuthorizationEndpoint()`: The configurer for the xref:protocol-endpoints.adoc#oauth2-device-authorization-endpoint[OAuth2 Device Authorization endpoint].
|
||||
<10> `deviceVerificationEndpoint()`: The configurer for the xref:protocol-endpoints.adoc#oauth2-device-verification-endpoint[OAuth2 Device Verification endpoint].
|
||||
<11> `tokenEndpoint()`: The configurer for the xref:protocol-endpoints.adoc#oauth2-token-endpoint[OAuth2 Token endpoint].
|
||||
<12> `tokenIntrospectionEndpoint()`: The configurer for the xref:protocol-endpoints.adoc#oauth2-token-introspection-endpoint[OAuth2 Token Introspection endpoint].
|
||||
<13> `tokenRevocationEndpoint()`: The configurer for the xref:protocol-endpoints.adoc#oauth2-token-revocation-endpoint[OAuth2 Token Revocation endpoint].
|
||||
<14> `authorizationServerMetadataEndpoint()`: The configurer for the xref:protocol-endpoints.adoc#oauth2-authorization-server-metadata-endpoint[OAuth2 Authorization Server Metadata endpoint].
|
||||
<15> `providerConfigurationEndpoint()`: The configurer for the xref:protocol-endpoints.adoc#oidc-provider-configuration-endpoint[OpenID Connect 1.0 Provider Configuration endpoint].
|
||||
<16> `logoutEndpoint()`: The configurer for the xref:protocol-endpoints.adoc#oidc-logout-endpoint[OpenID Connect 1.0 Logout endpoint].
|
||||
<17> `userInfoEndpoint()`: The configurer for the xref:protocol-endpoints.adoc#oidc-user-info-endpoint[OpenID Connect 1.0 UserInfo endpoint].
|
||||
<18> `clientRegistrationEndpoint()`: The configurer for the xref:protocol-endpoints.adoc#oidc-client-registration-endpoint[OpenID Connect 1.0 Client Registration endpoint].
|
||||
|
||||
[[configuring-authorization-server-settings]]
|
||||
== Configuring Authorization Server Settings
|
||||
|
||||
`AuthorizationServerSettings` contains the configuration settings for the OAuth2 authorization server.
|
||||
It specifies the `URI` for the protocol endpoints as well as the https://datatracker.ietf.org/doc/html/rfc8414#section-2[issuer identifier].
|
||||
The default `URI` for the protocol endpoints are as follows:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
public final class AuthorizationServerSettings extends AbstractSettings {
|
||||
|
||||
...
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder()
|
||||
.authorizationEndpoint("/oauth2/authorize")
|
||||
.pushedAuthorizationRequestEndpoint("/oauth2/par")
|
||||
.deviceAuthorizationEndpoint("/oauth2/device_authorization")
|
||||
.deviceVerificationEndpoint("/oauth2/device_verification")
|
||||
.tokenEndpoint("/oauth2/token")
|
||||
.tokenIntrospectionEndpoint("/oauth2/introspect")
|
||||
.tokenRevocationEndpoint("/oauth2/revoke")
|
||||
.jwkSetEndpoint("/oauth2/jwks")
|
||||
.oidcLogoutEndpoint("/connect/logout")
|
||||
.oidcUserInfoEndpoint("/userinfo")
|
||||
.oidcClientRegistrationEndpoint("/connect/register");
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
`AuthorizationServerSettings` is a *REQUIRED* component.
|
||||
|
||||
[TIP]
|
||||
xref:configuration-model.adoc#default-configuration[`@Import(OAuth2AuthorizationServerConfiguration.class)`] automatically registers an `AuthorizationServerSettings` `@Bean`, if not already provided.
|
||||
|
||||
The following example shows how to customize the configuration settings and register an `AuthorizationServerSettings` `@Bean`:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public AuthorizationServerSettings authorizationServerSettings() {
|
||||
return AuthorizationServerSettings.builder()
|
||||
.issuer("https://example.com")
|
||||
.authorizationEndpoint("/oauth2/v1/authorize")
|
||||
.pushedAuthorizationRequestEndpoint("/oauth2/v1/par")
|
||||
.deviceAuthorizationEndpoint("/oauth2/v1/device_authorization")
|
||||
.deviceVerificationEndpoint("/oauth2/v1/device_verification")
|
||||
.tokenEndpoint("/oauth2/v1/token")
|
||||
.tokenIntrospectionEndpoint("/oauth2/v1/introspect")
|
||||
.tokenRevocationEndpoint("/oauth2/v1/revoke")
|
||||
.jwkSetEndpoint("/oauth2/v1/jwks")
|
||||
.oidcLogoutEndpoint("/connect/v1/logout")
|
||||
.oidcUserInfoEndpoint("/connect/v1/userinfo")
|
||||
.oidcClientRegistrationEndpoint("/connect/v1/register")
|
||||
.build();
|
||||
}
|
||||
----
|
||||
|
||||
The `AuthorizationServerContext` is a context object that holds information of the Authorization Server runtime environment.
|
||||
It provides access to the `AuthorizationServerSettings` and the "`current`" issuer identifier.
|
||||
|
||||
[NOTE]
|
||||
If the issuer identifier is not configured in `AuthorizationServerSettings.builder().issuer(String)`, it is resolved from the current request.
|
||||
|
||||
[NOTE]
|
||||
The `AuthorizationServerContext` is accessible through the `AuthorizationServerContextHolder`, which associates it with the current request thread by using a `ThreadLocal`.
|
||||
|
||||
[[configuring-client-authentication]]
|
||||
== Configuring Client Authentication
|
||||
|
||||
`OAuth2ClientAuthenticationConfigurer` provides the ability to customize https://datatracker.ietf.org/doc/html/rfc6749#section-2.3[OAuth2 client authentication].
|
||||
It defines extension points that let you customize the pre-processing, main processing, and post-processing logic for client authentication requests.
|
||||
|
||||
`OAuth2ClientAuthenticationConfigurer` provides the following configuration options:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
|
||||
OAuth2AuthorizationServerConfigurer.authorizationServer();
|
||||
|
||||
http
|
||||
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
|
||||
.with(authorizationServerConfigurer, (authorizationServer) ->
|
||||
authorizationServer
|
||||
.clientAuthentication(clientAuthentication ->
|
||||
clientAuthentication
|
||||
.authenticationConverter(authenticationConverter) <1>
|
||||
.authenticationConverters(authenticationConvertersConsumer) <2>
|
||||
.authenticationProvider(authenticationProvider) <3>
|
||||
.authenticationProviders(authenticationProvidersConsumer) <4>
|
||||
.authenticationSuccessHandler(authenticationSuccessHandler) <5>
|
||||
.errorResponseHandler(errorResponseHandler) <6>
|
||||
)
|
||||
);
|
||||
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
<1> `authenticationConverter()`: Adds an `AuthenticationConverter` (_pre-processor_) used when attempting to extract client credentials from `HttpServletRequest` to an instance of `OAuth2ClientAuthenticationToken`.
|
||||
<2> `authenticationConverters()`: Sets the `Consumer` providing access to the `List` of default and (optionally) added ``AuthenticationConverter``'s allowing the ability to add, remove, or customize a specific `AuthenticationConverter`.
|
||||
<3> `authenticationProvider()`: Adds an `AuthenticationProvider` (_main processor_) used for authenticating the `OAuth2ClientAuthenticationToken`.
|
||||
<4> `authenticationProviders()`: Sets the `Consumer` providing access to the `List` of default and (optionally) added ``AuthenticationProvider``'s allowing the ability to add, remove, or customize a specific `AuthenticationProvider`.
|
||||
<5> `authenticationSuccessHandler()`: The `AuthenticationSuccessHandler` (_post-processor_) used for handling a successful client authentication and associating the `OAuth2ClientAuthenticationToken` to the `SecurityContext`.
|
||||
<6> `errorResponseHandler()`: The `AuthenticationFailureHandler` (_post-processor_) used for handling a failed client authentication and returning the https://datatracker.ietf.org/doc/html/rfc6749#section-5.2[`OAuth2Error` response].
|
||||
|
||||
`OAuth2ClientAuthenticationConfigurer` configures the `OAuth2ClientAuthenticationFilter` and registers it with the OAuth2 authorization server `SecurityFilterChain` `@Bean`.
|
||||
`OAuth2ClientAuthenticationFilter` is the `Filter` that processes client authentication requests.
|
||||
|
||||
By default, client authentication is required for the xref:protocol-endpoints.adoc#oauth2-token-endpoint[OAuth2 Token endpoint], the xref:protocol-endpoints.adoc#oauth2-token-introspection-endpoint[OAuth2 Token Introspection endpoint], and the xref:protocol-endpoints.adoc#oauth2-token-revocation-endpoint[OAuth2 Token Revocation endpoint].
|
||||
The supported client authentication methods are `client_secret_basic`, `client_secret_post`, `private_key_jwt`, `client_secret_jwt`, `tls_client_auth`, `self_signed_tls_client_auth`, and `none` (public clients).
|
||||
|
||||
`OAuth2ClientAuthenticationFilter` is configured with the following defaults:
|
||||
|
||||
* `*AuthenticationConverter*` -- A `DelegatingAuthenticationConverter` composed of `JwtClientAssertionAuthenticationConverter`, `X509ClientCertificateAuthenticationConverter`, `ClientSecretBasicAuthenticationConverter`, `ClientSecretPostAuthenticationConverter`, and `PublicClientAuthenticationConverter`.
|
||||
* `*AuthenticationManager*` -- An `AuthenticationManager` composed of `JwtClientAssertionAuthenticationProvider`, `X509ClientCertificateAuthenticationProvider`, `ClientSecretAuthenticationProvider`, and `PublicClientAuthenticationProvider`.
|
||||
* `*AuthenticationSuccessHandler*` -- An internal implementation that associates the "`authenticated`" `OAuth2ClientAuthenticationToken` (current `Authentication`) to the `SecurityContext`.
|
||||
* `*AuthenticationFailureHandler*` -- An internal implementation that uses the `OAuth2Error` associated with the `OAuth2AuthenticationException` to return the OAuth2 error response.
|
||||
|
||||
[[configuring-client-authentication-customizing-jwt-client-assertion-validation]]
|
||||
=== Customizing Jwt Client Assertion Validation
|
||||
|
||||
`JwtClientAssertionDecoderFactory.DEFAULT_JWT_VALIDATOR_FACTORY` is the default factory that provides an `OAuth2TokenValidator<Jwt>` for the specified `RegisteredClient` and is used for validating the `iss`, `sub`, `aud`, `exp` and `nbf` claims of the `Jwt` client assertion.
|
||||
|
||||
`JwtClientAssertionDecoderFactory` provides the ability to override the default `Jwt` client assertion validation by supplying a custom factory of type `Function<RegisteredClient, OAuth2TokenValidator<Jwt>>` to `setJwtValidatorFactory()`.
|
||||
|
||||
[NOTE]
|
||||
`JwtClientAssertionDecoderFactory` is the default `JwtDecoderFactory` used by `JwtClientAssertionAuthenticationProvider` that provides a `JwtDecoder` for the specified `RegisteredClient` and is used for authenticating a `Jwt` Bearer Token during OAuth2 client authentication.
|
||||
|
||||
A common use case for customizing `JwtClientAssertionDecoderFactory` is to validate additional claims in the `Jwt` client assertion.
|
||||
|
||||
The following example shows how to configure `JwtClientAssertionAuthenticationProvider` with a customized `JwtClientAssertionDecoderFactory` that validates an additional claim in the `Jwt` client assertion:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
|
||||
OAuth2AuthorizationServerConfigurer.authorizationServer();
|
||||
|
||||
http
|
||||
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
|
||||
.with(authorizationServerConfigurer, (authorizationServer) ->
|
||||
authorizationServer
|
||||
.clientAuthentication(clientAuthentication ->
|
||||
clientAuthentication
|
||||
.authenticationProviders(configureJwtClientAssertionValidator())
|
||||
)
|
||||
);
|
||||
|
||||
return http.build();
|
||||
}
|
||||
|
||||
private Consumer<List<AuthenticationProvider>> configureJwtClientAssertionValidator() {
|
||||
return (authenticationProviders) ->
|
||||
authenticationProviders.forEach((authenticationProvider) -> {
|
||||
if (authenticationProvider instanceof JwtClientAssertionAuthenticationProvider) {
|
||||
// Customize JwtClientAssertionDecoderFactory
|
||||
JwtClientAssertionDecoderFactory jwtDecoderFactory = new JwtClientAssertionDecoderFactory();
|
||||
Function<RegisteredClient, OAuth2TokenValidator<Jwt>> jwtValidatorFactory = (registeredClient) ->
|
||||
new DelegatingOAuth2TokenValidator<>(
|
||||
// Use default validators
|
||||
JwtClientAssertionDecoderFactory.DEFAULT_JWT_VALIDATOR_FACTORY.apply(registeredClient),
|
||||
// Add custom validator
|
||||
new JwtClaimValidator<>("claim", "value"::equals));
|
||||
jwtDecoderFactory.setJwtValidatorFactory(jwtValidatorFactory);
|
||||
|
||||
((JwtClientAssertionAuthenticationProvider) authenticationProvider)
|
||||
.setJwtDecoderFactory(jwtDecoderFactory);
|
||||
}
|
||||
});
|
||||
}
|
||||
----
|
||||
|
||||
[[configuring-client-authentication-customizing-mutual-tls-client-authentication]]
|
||||
=== Customizing Mutual-TLS Client Authentication
|
||||
|
||||
`X509ClientCertificateAuthenticationProvider` is used for authenticating the client `X509Certificate` chain received when `ClientAuthenticationMethod.TLS_CLIENT_AUTH` or `ClientAuthenticationMethod.SELF_SIGNED_TLS_CLIENT_AUTH` method is used during OAuth2 client authentication.
|
||||
It is also composed with a _"Certificate Verifier"_, which is used to verify the contents of the client `X509Certificate` after the TLS handshake has successfully completed.
|
||||
|
||||
[[customizing-mutual-tls-client-authentication-pki-mutual-tls-method]]
|
||||
==== PKI Mutual-TLS Method
|
||||
|
||||
For the PKI Mutual-TLS (`ClientAuthenticationMethod.TLS_CLIENT_AUTH`) method, the default implementation of the certificate verifier verifies the subject distinguished name of the client `X509Certificate` against the setting `RegisteredClient.getClientSettings.getX509CertificateSubjectDN()`.
|
||||
|
||||
If you need to verify another attribute of the client `X509Certificate`, for example, a Subject Alternative Name (SAN) entry, the following example shows how to configure `X509ClientCertificateAuthenticationProvider` with a custom implementation of a certificate verifier:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
|
||||
OAuth2AuthorizationServerConfigurer.authorizationServer();
|
||||
|
||||
http
|
||||
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
|
||||
.with(authorizationServerConfigurer, (authorizationServer) ->
|
||||
authorizationServer
|
||||
.clientAuthentication(clientAuthentication ->
|
||||
clientAuthentication
|
||||
.authenticationProviders(configureX509ClientCertificateVerifier())
|
||||
)
|
||||
);
|
||||
|
||||
return http.build();
|
||||
}
|
||||
|
||||
private Consumer<List<AuthenticationProvider>> configureX509ClientCertificateVerifier() {
|
||||
return (authenticationProviders) ->
|
||||
authenticationProviders.forEach((authenticationProvider) -> {
|
||||
if (authenticationProvider instanceof X509ClientCertificateAuthenticationProvider) {
|
||||
Consumer<OAuth2ClientAuthenticationContext> certificateVerifier = (clientAuthenticationContext) -> {
|
||||
OAuth2ClientAuthenticationToken clientAuthentication = clientAuthenticationContext.getAuthentication();
|
||||
RegisteredClient registeredClient = clientAuthenticationContext.getRegisteredClient();
|
||||
X509Certificate[] clientCertificateChain = (X509Certificate[]) clientAuthentication.getCredentials();
|
||||
X509Certificate clientCertificate = clientCertificateChain[0];
|
||||
|
||||
// TODO Verify Subject Alternative Name (SAN) entry
|
||||
|
||||
};
|
||||
|
||||
((X509ClientCertificateAuthenticationProvider) authenticationProvider)
|
||||
.setCertificateVerifier(certificateVerifier);
|
||||
}
|
||||
});
|
||||
}
|
||||
----
|
||||
|
||||
[[customizing-mutual-tls-client-authentication-self-signed-certificate-mutual-tls-method]]
|
||||
==== Self-Signed Certificate Mutual-TLS Method
|
||||
|
||||
For the Self-Signed Certificate Mutual-TLS (`ClientAuthenticationMethod.SELF_SIGNED_TLS_CLIENT_AUTH`) method, the default implementation of the certificate verifier will retrieve the client's JSON Web Key Set using the setting `RegisteredClient.getClientSettings.getJwkSetUrl()` and expect to find a match against the client `X509Certificate` received during the TLS handshake.
|
||||
|
||||
[NOTE]
|
||||
The `RegisteredClient.getClientSettings.getJwkSetUrl()` setting is used to retrieve the client's certificates via a JSON Web Key (JWK) Set.
|
||||
A certificate is represented with the `x5c` parameter of an individual JWK within the set.
|
||||
|
||||
[[customizing-mutual-tls-client-authentication-client-certificate-bound-access-tokens]]
|
||||
==== Client Certificate-Bound Access Tokens
|
||||
|
||||
When Mutual-TLS client authentication is used at the token endpoint, the authorization server is able to bind the issued access token to the client's `X509Certificate`.
|
||||
The binding is accomplished by computing the SHA-256 thumbprint of the client's `X509Certificate` and associating the thumbprint with the access token.
|
||||
For example, a JWT access token would include a `x5t#S256` claim, containing the `X509Certificate` thumbprint, within the top-level `cnf` (confirmation method) claim.
|
||||
|
||||
Binding the access token to the client's `X509Certificate` provides the ability to implement a proof-of-possession mechanism during protected resource access.
|
||||
For example, the protected resource would obtain the client's `X509Certificate` used during Mutual-TLS authentication and then verify that the certificate thumbprint matches the `x5t#S256` claim associated with the access token.
|
||||
|
||||
The following example shows how to enable certificate-bound access tokens for a client:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
RegisteredClient mtlsClient = RegisteredClient.withId(UUID.randomUUID().toString())
|
||||
.clientId("mtls-client")
|
||||
.clientAuthenticationMethod(ClientAuthenticationMethod.TLS_CLIENT_AUTH)
|
||||
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
|
||||
.scope("scope-a")
|
||||
.clientSettings(
|
||||
ClientSettings.builder()
|
||||
.x509CertificateSubjectDN("CN=mtls-client,OU=Spring Samples,O=Spring,C=US")
|
||||
.build()
|
||||
)
|
||||
.tokenSettings(
|
||||
TokenSettings.builder()
|
||||
.x509CertificateBoundAccessTokens(true)
|
||||
.build()
|
||||
)
|
||||
.build();
|
||||
----
|
||||
+534
@@ -0,0 +1,534 @@
|
||||
[[core-model-components]]
|
||||
= Core Model / Components
|
||||
|
||||
[[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> 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 {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`, `refresh_token`, `urn:ietf:params:oauth:grant-type:device_code`, and `urn:ietf:params:oauth:grant-type:token-exchange`.
|
||||
<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> `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 https://datatracker.ietf.org/doc/html/rfc7636[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.
|
||||
|
||||
[[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#customizing-the-configuration[`OAuth2AuthorizationServerConfigurer`]:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
|
||||
OAuth2AuthorizationServerConfigurer.authorizationServer();
|
||||
|
||||
http
|
||||
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
|
||||
.with(authorizationServerConfigurer, (authorizationServer) ->
|
||||
authorizationServer
|
||||
.registeredClientRepository(registeredClientRepository)
|
||||
)
|
||||
...
|
||||
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
The `OAuth2AuthorizationServerConfigurer` is useful when applying multiple configuration options simultaneously.
|
||||
|
||||
[[oauth2-authorization]]
|
||||
== OAuth2Authorization
|
||||
|
||||
An `OAuth2Authorization` is a representation of an OAuth2 authorization, which holds state related to the authorization granted to a xref:core-model-components.adoc#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 {spring-security-api-base-url}/org/springframework/security/oauth2/core/OAuth2AccessToken.html[`OAuth2AccessToken`], an (optional) {spring-security-api-base-url}/org/springframework/security/oauth2/core/OAuth2RefreshToken.html[`OAuth2RefreshToken`], and additional state specific to the executed authorization grant type.
|
||||
|
||||
The {spring-security-api-base-url}/org/springframework/security/oauth2/core/OAuth2Token.html[`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 {spring-security-api-base-url}/org/springframework/security/oauth2/core/oidc/OidcIdToken.html[`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 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 xref:core-model-components.adoc#registered-client[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.
|
||||
|
||||
`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#customizing-the-configuration[`OAuth2AuthorizationServerConfigurer`]:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
|
||||
OAuth2AuthorizationServerConfigurer.authorizationServer();
|
||||
|
||||
http
|
||||
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
|
||||
.with(authorizationServerConfigurer, (authorizationServer) ->
|
||||
authorizationServer
|
||||
.authorizationService(authorizationService)
|
||||
)
|
||||
...
|
||||
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
The `OAuth2AuthorizationServerConfigurer` is useful when applying multiple configuration options simultaneously.
|
||||
|
||||
[[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 xref:core-model-components.adoc#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 xref:core-model-components.adoc#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#customizing-the-configuration[`OAuth2AuthorizationServerConfigurer`]:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
|
||||
OAuth2AuthorizationServerConfigurer.authorizationServer();
|
||||
|
||||
http
|
||||
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
|
||||
.with(authorizationServerConfigurer, (authorizationServer) ->
|
||||
authorizationServer
|
||||
.authorizationConsentService(authorizationConsentService)
|
||||
)
|
||||
...
|
||||
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
The `OAuth2AuthorizationServerConfigurer` is useful when applying multiple configuration options simultaneously.
|
||||
|
||||
[[oauth2-token-context]]
|
||||
== OAuth2TokenContext
|
||||
|
||||
An `OAuth2TokenContext` is a context object that holds information associated with an `OAuth2Token` and is used by an xref:core-model-components.adoc#oauth2-token-generator[OAuth2TokenGenerator] and xref:core-model-components.adoc#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 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 xref:core-model-components.adoc#registered-client[RegisteredClient] associated with the authorization grant.
|
||||
<2> `getPrincipal()`: The `Authentication` instance of the resource owner (or client).
|
||||
<3> `getAuthorizationServerContext()`: The xref:configuration-model.adoc#configuring-authorization-server-settings[`AuthorizationServerContext`] object that holds information of the Authorization Server runtime environment.
|
||||
<4> `getAuthorization()`: The xref:core-model-components.adoc#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` associated with the authorization grant.
|
||||
<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 xref:core-model-components.adoc#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 xref:core-model-components.adoc#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 xref:core-model-components.adoc#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`.
|
||||
|
||||
[NOTE]
|
||||
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#customizing-the-configuration[`OAuth2AuthorizationServerConfigurer`]:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
|
||||
OAuth2AuthorizationServerConfigurer.authorizationServer();
|
||||
|
||||
http
|
||||
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
|
||||
.with(authorizationServerConfigurer, (authorizationServer) ->
|
||||
authorizationServer
|
||||
.tokenGenerator(tokenGenerator)
|
||||
)
|
||||
...
|
||||
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
The `OAuth2AuthorizationServerConfigurer` is useful when applying multiple configuration options simultaneously.
|
||||
|
||||
[[oauth2-token-customizer]]
|
||||
== OAuth2TokenCustomizer
|
||||
|
||||
An `OAuth2TokenCustomizer` provides the ability to customize the attributes of an `OAuth2Token`, which are accessible in the provided xref:core-model-components.adoc#oauth2-token-context[OAuth2TokenContext].
|
||||
It is used by an xref:core-model-components.adoc#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
|
||||
|
||||
};
|
||||
}
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
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.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.
|
||||
|
||||
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 -> {
|
||||
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
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
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`.
|
||||
|
||||
[TIP]
|
||||
For an example showing how you can xref:guides/how-to-userinfo.adoc#customize-id-token[customize the ID token], see the guide xref:guides/how-to-userinfo.adoc[How-to: Customize the OpenID Connect 1.0 UserInfo response].
|
||||
|
||||
[[session-registry]]
|
||||
== SessionRegistry
|
||||
|
||||
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 xref:protocol-endpoints.adoc#oauth2-authorization-endpoint[OAuth2 Authorization Endpoint] for registering new authenticated sessions.
|
||||
|
||||
[NOTE]
|
||||
If a `SessionRegistry` `@Bean` is not registered, the default implementation `SessionRegistryImpl` will be used.
|
||||
|
||||
[IMPORTANT]
|
||||
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.
|
||||
|
||||
When a logout is requested by an End-User, the xref:protocol-endpoints.adoc#oidc-logout-endpoint[OpenID Connect 1.0 Logout Endpoint] uses the `SessionRegistry` to lookup the `SessionInformation` associated to the authenticated End-User to perform the logout.
|
||||
|
||||
If Spring Security's {spring-security-reference-base-url}/servlet/authentication/session-management.html#ns-concurrent-sessions[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.
|
||||
|
||||
The following example shows how to register a `SessionRegistry` `@Bean` and `HttpSessionEventPublisher` `@Bean` (required by `SessionRegistryImpl`):
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SessionRegistry sessionRegistry() {
|
||||
return new SessionRegistryImpl();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HttpSessionEventPublisher httpSessionEventPublisher() {
|
||||
return new HttpSessionEventPublisher();
|
||||
}
|
||||
----
|
||||
@@ -0,0 +1,24 @@
|
||||
[[getting-help]]
|
||||
= Getting Help
|
||||
:page-section-summary-toc: 1
|
||||
|
||||
[[community]]
|
||||
== Community
|
||||
|
||||
Welcome to the https://docs.spring.io/spring-security/reference/community.html[Spring Security Community].
|
||||
Spring Authorization Server is an open source project led by the Spring Security team.
|
||||
If you need help with Spring Authorization Server, we are here to help.
|
||||
|
||||
[[resources]]
|
||||
== Resources
|
||||
|
||||
The following are some of the best ways to get help:
|
||||
|
||||
* Try the xref:how-to.adoc[How-to guides]. They provide solutions to the most common questions.
|
||||
* Learn the Spring Security basics that Spring Authorization Server builds on. If you are starting out with Spring Security, check the https://spring.io/projects/spring-security#learn[reference documentation] or try one of the https://github.com/spring-projects/spring-security-samples[samples].
|
||||
* Read through xref:index.adoc[this documentation].
|
||||
* Try one of our many https://github.com/spring-projects/spring-authorization-server/tree/main/samples[sample applications].
|
||||
* Ask a question on Stack Overflow with the https://stackoverflow.com/questions/tagged/spring-authorization-server[`spring-authorization-server`] tag.
|
||||
* Report bugs and enhancement requests on https://github.com/spring-projects/spring-authorization-server/issues[GitHub].
|
||||
|
||||
NOTE: Spring Authorization Server is open source, including the documentation. If you find problems with the docs or if you want to improve them, please https://github.com/spring-projects/spring-authorization-server[get involved].
|
||||
@@ -0,0 +1,107 @@
|
||||
|
||||
[[getting-started]]
|
||||
= Getting Started
|
||||
|
||||
If you are just getting started with Spring Authorization Server, the following sections walk you through creating your first application.
|
||||
|
||||
[[system-requirements]]
|
||||
== System Requirements
|
||||
|
||||
Spring Authorization Server requires a Java 17 or higher Runtime Environment.
|
||||
|
||||
[[installing-spring-authorization-server]]
|
||||
== Installing Spring Authorization Server
|
||||
|
||||
Spring Authorization Server can be used anywhere you already use https://docs.spring.io/spring-security/reference/prerequisites.html[Spring Security].
|
||||
|
||||
The easiest way to begin using Spring Authorization Server is by creating a https://spring.io/projects/spring-boot[Spring Boot]-based application.
|
||||
You can use https://start.spring.io[start.spring.io] to generate a basic project or use the https://github.com/spring-projects/spring-authorization-server/tree/main/samples/default-authorizationserver[default authorization server sample] as a guide.
|
||||
Then add Spring Boot's starter for Spring Authorization Server as a dependency:
|
||||
|
||||
[tabs]
|
||||
======
|
||||
Maven::
|
||||
+
|
||||
[[spring-boot-maven-dependency]]
|
||||
[source,xml,role="primary",subs="attributes,verbatim"]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-oauth2-authorization-server</artifactId>
|
||||
</dependency>
|
||||
----
|
||||
|
||||
Gradle::
|
||||
+
|
||||
[[spring-boot-gradle-dependency]]
|
||||
[source,gradle,role="secondary",subs="attributes,verbatim"]
|
||||
----
|
||||
implementation "org.springframework.boot:spring-boot-starter-oauth2-authorization-server"
|
||||
----
|
||||
======
|
||||
|
||||
TIP: See https://docs.spring.io/spring-boot/docs/current/reference/html/getting-started.html#getting-started.installing[Installing Spring Boot] for more information on using Spring Boot with Maven or Gradle.
|
||||
|
||||
Alternatively, you can add Spring Authorization Server without Spring Boot using the following example:
|
||||
|
||||
[tabs]
|
||||
======
|
||||
Maven::
|
||||
+
|
||||
[[maven-dependency]]
|
||||
[source,xml,role="primary",subs="attributes,verbatim"]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-oauth2-authorization-server</artifactId>
|
||||
<version>{spring-authorization-server-version}</version>
|
||||
</dependency>
|
||||
----
|
||||
|
||||
Gradle::
|
||||
+
|
||||
[[gradle-dependency]]
|
||||
[source,gradle,role="secondary",subs="attributes,verbatim"]
|
||||
----
|
||||
implementation "org.springframework.security:spring-security-oauth2-authorization-server:{spring-authorization-server-version}"
|
||||
----
|
||||
======
|
||||
|
||||
[[developing-your-first-application]]
|
||||
== Developing Your First Application
|
||||
|
||||
To get started, you need the minimum required components defined as a `@Bean`. When using the `spring-boot-starter-oauth2-authorization-server` dependency, define the following properties and Spring Boot will provide the necessary `@Bean` definitions for you:
|
||||
|
||||
[[application-yml]]
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
include::{docs-java}/sample/gettingstarted/application.yml[]
|
||||
----
|
||||
|
||||
TIP: Beyond the Getting Started experience, most users will want to customize the default configuration. The xref:getting-started.adoc#defining-required-components[next section] demonstrates providing all of the necessary beans yourself.
|
||||
|
||||
[[defining-required-components]]
|
||||
== Defining Required Components
|
||||
|
||||
If you want to customize the default configuration (regardless of whether you're using Spring Boot), you can define the minimum required components as a `@Bean` in a Spring `@Configuration`.
|
||||
|
||||
These components can be defined as follows:
|
||||
|
||||
[[sample.gettingstarted]]
|
||||
.SecurityConfig.java
|
||||
[source,java]
|
||||
----
|
||||
include::{docs-java}/sample/gettingstarted/SecurityConfig.java[]
|
||||
----
|
||||
|
||||
This is a minimal configuration for getting started quickly. To understand what each component is used for, see the following descriptions:
|
||||
|
||||
<1> A Spring Security filter chain for the xref:protocol-endpoints.adoc[Protocol Endpoints].
|
||||
<2> A Spring Security filter chain for https://docs.spring.io/spring-security/reference/servlet/authentication/index.html[authentication].
|
||||
<3> An instance of {spring-security-api-base-url}/org/springframework/security/core/userdetails/UserDetailsService.html[`UserDetailsService`] for retrieving users to authenticate.
|
||||
<4> An instance of xref:core-model-components.adoc#registered-client-repository[`RegisteredClientRepository`] for managing clients.
|
||||
<5> An instance of `com.nimbusds.jose.jwk.source.JWKSource` for signing access tokens.
|
||||
<6> An instance of `java.security.KeyPair` with keys generated on startup used to create the `JWKSource` above.
|
||||
<7> An instance of {spring-security-api-base-url}/org/springframework/security/oauth2/jwt/JwtDecoder.html[`JwtDecoder`] for decoding signed access tokens.
|
||||
<8> An instance of xref:configuration-model#configuring-authorization-server-settings[`AuthorizationServerSettings`] to configure Spring Authorization Server.
|
||||
@@ -0,0 +1,18 @@
|
||||
:noheader:
|
||||
[[top]]
|
||||
= Spring Authorization Server Reference
|
||||
|
||||
[horizontal]
|
||||
xref:overview.adoc[Overview] :: Introduction, use cases and feature list
|
||||
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] :: Default configuration and customizing the configuration
|
||||
xref:core-model-components.adoc[Core Model / Components] :: Core domain model and component interfaces
|
||||
xref:protocol-endpoints.adoc[Protocol Endpoints] :: OAuth2 and OpenID Connect 1.0 protocol endpoint implementations
|
||||
xref:how-to.adoc[How-to Guides] :: Guides to get the most from Spring Authorization Server
|
||||
|
||||
Joe Grandja, Steve Riesenberg
|
||||
|
||||
Copyright © 2020 - 2024
|
||||
|
||||
Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.
|
||||
@@ -0,0 +1,119 @@
|
||||
[[overview]]
|
||||
= Overview
|
||||
|
||||
This site contains reference documentation and how-to guides for Spring Authorization Server.
|
||||
|
||||
[[introducing-spring-authorization-server]]
|
||||
== Introducing Spring Authorization Server
|
||||
|
||||
Spring Authorization Server is a framework that provides implementations of the https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-07[OAuth 2.1] and https://openid.net/specs/openid-connect-core-1_0.html[OpenID Connect 1.0] specifications and other related specifications.
|
||||
It is built on top of https://spring.io/projects/spring-security[Spring Security] to provide a secure, light-weight, and customizable foundation for building OpenID Connect 1.0 Identity Providers and OAuth2 Authorization Server products.
|
||||
|
||||
[[use-cases]]
|
||||
== Use Cases
|
||||
|
||||
The following list provides some use cases for using Spring Authorization Server compared to using an open source or commercial OAuth2 or OpenID Connect 1.0 Provider product.
|
||||
|
||||
* Provides full control of configuration and customization when advanced customization scenarios are required.
|
||||
* Preference for a light-weight authorization server compared to a commercial product that includes all the "bells and whistles".
|
||||
* Potential savings in software licensing and/or hosting costs.
|
||||
* Quick startup and ease of use during development using the familiar Spring programming model.
|
||||
|
||||
[[feature-list]]
|
||||
== Feature List
|
||||
|
||||
Spring Authorization Server supports the following features:
|
||||
|
||||
[cols="2a,4a,6a"]
|
||||
|===
|
||||
|Category |Feature |Related specifications
|
||||
|
||||
|xref:protocol-endpoints.adoc#oauth2-token-endpoint[Authorization Grant]
|
||||
|
|
||||
* Authorization Code
|
||||
** xref:protocol-endpoints.adoc#oauth2-authorization-endpoint[User Consent]
|
||||
* Client Credentials
|
||||
* Refresh Token
|
||||
* Device Code
|
||||
** xref:protocol-endpoints.adoc#oauth2-device-verification-endpoint[User Consent]
|
||||
* Token Exchange
|
||||
|
|
||||
* The OAuth 2.1 Authorization Framework (https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-07[draft])
|
||||
** https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-07#section-4.1[Authorization Code Grant]
|
||||
** https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-07#section-4.2[Client Credentials Grant]
|
||||
** https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-07#section-4.3[Refresh Token Grant]
|
||||
* OpenID Connect Core 1.0 (https://openid.net/specs/openid-connect-core-1_0.html[spec])
|
||||
** https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth[Authorization Code Flow]
|
||||
* OAuth 2.0 Device Authorization Grant
|
||||
(https://tools.ietf.org/html/rfc8628[spec])
|
||||
** https://tools.ietf.org/html/rfc8628#section-3[Device Flow]
|
||||
* OAuth 2.0 Token Exchange (https://datatracker.ietf.org/doc/html/rfc8693[spec])
|
||||
** https://datatracker.ietf.org/doc/html/rfc8693#section-2[Token Exchange Flow]
|
||||
|
||||
|xref:core-model-components.adoc#oauth2-token-generator[Token Formats]
|
||||
|
|
||||
* Self-contained (JWT)
|
||||
* Reference (Opaque)
|
||||
|
|
||||
* JSON Web Token (JWT) (https://tools.ietf.org/html/rfc7519[RFC 7519])
|
||||
* JSON Web Signature (JWS) (https://tools.ietf.org/html/rfc7515[RFC 7515])
|
||||
|
||||
|Token Types
|
||||
|
|
||||
* xref:protocol-endpoints.adoc#oauth2-token-endpoint-dpop-bound-access-tokens[DPoP-bound Access Tokens]
|
||||
|
|
||||
* OAuth 2.0 Demonstrating Proof of Possession (DPoP) (https://datatracker.ietf.org/doc/html/rfc9449[RFC 9449])
|
||||
|
||||
|xref:configuration-model.adoc#configuring-client-authentication[Client Authentication]
|
||||
|
|
||||
* `client_secret_basic`
|
||||
* `client_secret_post`
|
||||
* `client_secret_jwt`
|
||||
* `private_key_jwt`
|
||||
* `tls_client_auth`
|
||||
* `self_signed_tls_client_auth`
|
||||
* `none` (public clients)
|
||||
|
|
||||
* The OAuth 2.1 Authorization Framework (https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-07#section-2.4[Client Authentication])
|
||||
* JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication (https://tools.ietf.org/html/rfc7523[RFC 7523])
|
||||
* OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens (https://datatracker.ietf.org/doc/html/rfc8705[RFC 8705])
|
||||
* Proof Key for Code Exchange by OAuth Public Clients (PKCE) (https://tools.ietf.org/html/rfc7636[RFC 7636])
|
||||
|
||||
|xref:protocol-endpoints.adoc[Protocol Endpoints]
|
||||
|
|
||||
* xref:protocol-endpoints.adoc#oauth2-authorization-endpoint[OAuth2 Authorization Endpoint]
|
||||
* xref:protocol-endpoints.adoc#oauth2-pushed-authorization-request-endpoint[OAuth2 Pushed Authorization Request Endpoint]
|
||||
* xref:protocol-endpoints.adoc#oauth2-device-authorization-endpoint[OAuth2 Device Authorization Endpoint]
|
||||
* xref:protocol-endpoints.adoc#oauth2-device-verification-endpoint[OAuth2 Device Verification Endpoint]
|
||||
* xref:protocol-endpoints.adoc#oauth2-token-endpoint[OAuth2 Token Endpoint]
|
||||
* xref:protocol-endpoints.adoc#oauth2-token-introspection-endpoint[OAuth2 Token Introspection Endpoint]
|
||||
* xref:protocol-endpoints.adoc#oauth2-token-revocation-endpoint[OAuth2 Token Revocation Endpoint]
|
||||
* xref:protocol-endpoints.adoc#oauth2-authorization-server-metadata-endpoint[OAuth2 Authorization Server Metadata Endpoint]
|
||||
* xref:protocol-endpoints.adoc#jwk-set-endpoint[JWK Set Endpoint]
|
||||
* xref:protocol-endpoints.adoc#oidc-provider-configuration-endpoint[OpenID Connect 1.0 Provider Configuration Endpoint]
|
||||
* xref:protocol-endpoints.adoc#oidc-logout-endpoint[OpenID Connect 1.0 Logout Endpoint]
|
||||
* xref:protocol-endpoints.adoc#oidc-user-info-endpoint[OpenID Connect 1.0 UserInfo Endpoint]
|
||||
* xref:protocol-endpoints.adoc#oidc-client-registration-endpoint[OpenID Connect 1.0 Client Registration Endpoint]
|
||||
|
|
||||
* The OAuth 2.1 Authorization Framework (https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-07[draft])
|
||||
** https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-07#section-3.1[Authorization Endpoint]
|
||||
** https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-07#section-3.2[Token Endpoint]
|
||||
* OAuth 2.0 Pushed Authorization Requests (https://datatracker.ietf.org/doc/html/rfc9126[RFC 9126])
|
||||
** https://datatracker.ietf.org/doc/html/rfc9126#section-2[Pushed Authorization Request Endpoint]
|
||||
* OAuth 2.0 Device Authorization Grant (https://tools.ietf.org/html/rfc8628[RFC 8628])
|
||||
** https://tools.ietf.org/html/rfc8628#section-3.1[Device Authorization Endpoint]
|
||||
** https://tools.ietf.org/html/rfc8628#section-3.3[Device Verification Endpoint]
|
||||
* OAuth 2.0 Token Introspection (https://tools.ietf.org/html/rfc7662[RFC 7662])
|
||||
* OAuth 2.0 Token Revocation (https://tools.ietf.org/html/rfc7009[RFC 7009])
|
||||
* OAuth 2.0 Authorization Server Metadata (https://tools.ietf.org/html/rfc8414[RFC 8414])
|
||||
* JSON Web Key (JWK) (https://tools.ietf.org/html/rfc7517[RFC 7517])
|
||||
* OpenID Connect Discovery 1.0 (https://openid.net/specs/openid-connect-discovery-1_0.html[spec])
|
||||
** https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig[Provider Configuration Endpoint]
|
||||
* OpenID Connect RP-Initiated Logout 1.0 (https://openid.net/specs/openid-connect-rpinitiated-1_0.html[spec])
|
||||
** https://openid.net/specs/openid-connect-rpinitiated-1_0.html#RPLogout[Logout Endpoint]
|
||||
* OpenID Connect Core 1.0 (https://openid.net/specs/openid-connect-core-1_0.html[spec])
|
||||
** https://openid.net/specs/openid-connect-core-1_0.html#UserInfo[UserInfo Endpoint]
|
||||
* OpenID Connect Dynamic Client Registration 1.0 (https://openid.net/specs/openid-connect-registration-1_0.html[spec])
|
||||
** https://openid.net/specs/openid-connect-registration-1_0.html#ClientRegistration[Client Registration Endpoint]
|
||||
** https://openid.net/specs/openid-connect-registration-1_0.html#ClientConfigurationEndpoint[Client Configuration Endpoint]
|
||||
|===
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user