### Run Demo Sample Components Source: https://github.com/spring-projects/spring-authorization-server/blob/main/samples/README.adoc Commands to start the Authorization Server, Client, and Resource Server components using Gradle. ```bash ./gradlew -b samples/demo-authorizationserver/samples-demo-authorizationserver.gradle bootRun ``` ```bash ./gradlew -b samples/demo-client/samples-demo-client.gradle bootRun ``` ```bash ./gradlew -b samples/messages-resource/samples-messages-resource.gradle bootRun ``` -------------------------------- ### Generating a DPoP Proof JWT (Java Example) Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/protocol-endpoints.adoc Example code snippet in Java demonstrating how to generate a DPoP Proof JWT using Nimbus JOSE+JWT library. ```APIDOC ## Generating a DPoP Proof JWT ### Description This code example demonstrates how to generate a DPoP Proof JWT using the Nimbus JOSE+JWT library in Java. It includes setting up the JWK source, encoder, and constructing the JWT header and claims. ### Method ```java import com.nimbusds.jose.*; import com.nimbusds.jose.crypto.RS256Signer; import com.nimbusds.jose.jwk.JWKSet; import com.nimbusds.jose.jwk.RSAKey; import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.SignedJWT; import com.nimbusds.jwt.util.DateUtils; import java.time.Instant; import java.util.UUID; // Assume rsaKey is an instance of com.nimbusds.jose.jwk.RSAKey RSAKey rsaKey = ...; JWKSource jwkSource = (jwkSelector, securityContext) -> jwkSelector .select(new JWKSet(rsaKey)); NimbusJwtEncoder jwtEncoder = new NimbusJwtEncoder(jwkSource); JwsHeader jwsHeader = JwsHeader.with(SignatureAlgorithm.RS256) .type("dpop+jwt") .jwk(rsaKey.toPublicJWK().toJSONObject()) .build(); JwtClaimsSet claims = JwtClaimsSet.builder() .issuedAt(Instant.now()) .claim("htm", "POST") .claim("htu", "https://server.example.com/oauth2/token") .id(UUID.randomUUID().toString()) .build(); Jwt dPoPProof = jwtEncoder.encode(JwtEncoderParameters.from(jwsHeader, claims)); ``` ``` -------------------------------- ### Configure OAuth2 Client Authentication with Customization Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/configuration-model.adoc This example demonstrates how to configure the OAuth2 client authentication within the SecurityFilterChain. It shows how to access the clientAuthentication configurer to customize the authentication flow. ```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(myConverter) .authenticationProvider(myProvider) )); return http.build(); } ``` -------------------------------- ### GET /.well-known/oauth-authorization-server Source: https://context7.com/spring-projects/spring-authorization-server/llms.txt Retrieves the OAuth 2.0 Authorization Server metadata configuration. ```APIDOC ## GET /.well-known/oauth-authorization-server ### Description Returns the metadata configuration for the OAuth 2.0 Authorization Server. ### Method GET ### Endpoint /.well-known/oauth-authorization-server ### Response #### Success Response (200) - **issuer** (string) - The issuer URL - **authorization_endpoint** (string) - The authorization endpoint URL - **token_endpoint** (string) - The token endpoint URL - **jwks_uri** (string) - The JWK set endpoint URL #### Response Example { "issuer": "http://localhost:9000", "authorization_endpoint": "http://localhost:9000/oauth2/authorize", "token_endpoint": "http://localhost:9000/oauth2/token", "jwks_uri": "http://localhost:9000/oauth2/jwks" } ``` -------------------------------- ### Obtain Initial Access Token for Client Registration Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/guides/how-to-dynamic-client-registration.adoc This HTTP request example shows how to obtain an initial access token for dynamic client registration. It uses the 'client_credentials' grant type with the 'client.create' scope. The request must be authorized with the client's credentials. ```http POST /oauth2/token HTTP/1.1 Authorization: Basic Content-Type: application/x-www-form-urlencoded grant_type=client_credentials&scope=client.create ``` -------------------------------- ### Configure RegisteredClient for Authorization Code Grant (YAML) Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/core-model-components.adoc YAML configuration equivalent to the Java example for setting up a client registration. This includes provider details, client ID, secret, grant type, redirect URI, and scopes. ```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 ``` -------------------------------- ### Access Token Request with DPoP Proof Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/protocol-endpoints.adoc Example of an authorization code grant access token request including the DPoP proof in the `DPoP` header. ```APIDOC ## POST /oauth2/token ### Description Requests an access token with a DPoP proof. ### Method POST ### Endpoint /oauth2/token ### Parameters #### Header Parameters - **DPoP** (string) - Required - The DPoP proof JWT. - **Host** (string) - Required - The server host. - **Content-Type** (string) - Required - `application/x-www-form-urlencoded`. #### Request Body - **grant_type** (string) - Required - The authorization grant type (e.g., `authorization_code`). - **client_id** (string) - Required - The client identifier. - **code** (string) - Required - The authorization code. - **redirect_uri** (string) - Required - The redirect URI. - **code_verifier** (string) - Required - The code verifier for PKCE. ### Request Example ```shell POST /oauth2/token HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded DPoP: eyJraWQiOiJyc2EtandrLWtpZCIsInR5cCI6ImRwb3Arand0IiwiYWxnIjoiUlMyNTYiLCJqd2siOnsia3R5IjoiUlNBIiwiZSI6IkFRQUIiLCJraWQiOiJyc2EtandrLWtpZCIsIm4iOiIzRmxxSnI1VFJza0lRSWdkRTNEZDdEOWxib1dkY1RVVDhhLWZKUjdNQXZRbTdYWE5vWWttM3Y3TVFMMU5ZdER2TDJsOENBbmMwV2RTVElOVTZJUnZjNUtxbzJRNGNzTlg5U0hPbUVmem9ST2pRcWFoRWN2ZTFqQlhsdW9DWGRZdVlweDRfMXRmUmdHNmlpNFVoeGg2aUk4cU5NSlFYLWZMZnFoYmZZZnhCUVZSUHl3QmtBYklQNHgxRUFzYkM2RlNObWtoQ3hpTU5xRWd4YUlwWThDMmtKZEpfWklWLVdXNG5vRGR6cEtxSGN3bUI4RnNydW1sVllfRE5WdlVTRElpcGlxOVBiUDRIOTlUWE4xbzc0Nm9SYU5hMDdycTFob0NnTVNTeS04NVNhZ0NveGxteUUtRC1vZjlTc01ZOE9sOXQwcmR6cG9iQnVoeUpfbzVkZnZqS3cifX0.eyJodG0iOiJQT1NUIiwiaHR1IjoiaHR0cHM6Ly9zZXJ2ZXIuZXhhbXBsZS5jb20vb2F1dGgyL3Rva2VuIiwiaWF0IjoxNzQ2ODA2MzA1LCJqdGkiOiI0YjIzNDBkMi1hOTFmLTQwYTUtYmFhOS1kZDRlNWRlYWM4NjcifQ.wq8gJ_G6vpiEinfaY3WhereqCCLoeJOG8tnWBBAzRWx9F1KU5yAAWq-ZVCk_k07-h6DIqz2wgv6y9dVbNpRYwNwDUeik9qLRsC60M8YW7EFVyI3n_NpujLwzZeub_nDYMVnyn4ii0NaZrYHtoGXOlswQfS_-ET-jpC0XWm5nBZsCdUEXjOYtwaACC6Js-pyNwKmSLp5SKIk11jZUR5xIIopaQy521y9qJHhGRwzj8DQGsP7wMZ98UFL0E--1c-hh4rTy8PMeWCqRHdwjj_ry_eTe0DJFcxxYQdeL7-0_0CIO4Ayx5WHEpcUOIzBRoN32RsNpDZc-5slDNj9ku004DA grant_type=authorization_code&client_id=s6BhdRkqt&code=SplxlOBeZQQYbYS6WxSbIA&redirect_uri=https%3A%2F%2Fclient.example.com%2Fcb&code_verifier=bEaL42izcC-o-xBk0K2vuJ6U-y1p9r_wW2dFWIWgjz- ``` ### Response #### Success Response (200) - **access_token** (string) - The issued access token. - **token_type** (string) - The token type, which will be `DPoP` if bound to a public key. - **expires_in** (integer) - The lifetime in seconds of the access token. #### Response Example ```json { "access_token": "Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU", "token_type": "DPoP", "expires_in": 2677 } ``` ``` -------------------------------- ### Configure OAuth2AuthorizationConsentService via SecurityFilterChain Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/core-model-components.adoc This example shows how to configure the OAuth2AuthorizationConsentService using the OAuth2AuthorizationServerConfigurer within a SecurityFilterChain. This approach is useful for applying multiple configuration options. ```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(); } ``` -------------------------------- ### Define OpenID Connect Provider Configuration Metadata Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/guides/how-to-multitenancy.adoc Example JSON response for an OpenID Provider Configuration request, illustrating how an issuer identifier with a path component serves as a tenant identifier. ```json { "issuer": "http://localhost:9000/issuer1", "authorization_endpoint": "http://localhost:9000/issuer1/oauth2/authorize", "token_endpoint": "http://localhost:9000/issuer1/oauth2/token", "jwks_uri": "http://localhost:9000/issuer1/oauth2/jwks", "revocation_endpoint": "http://localhost:9000/issuer1/oauth2/revoke", "introspection_endpoint": "http://localhost:9000/issuer1/oauth2/introspect", ... } ``` -------------------------------- ### Registering a JwtDecoder Bean Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/configuration-model.adoc Provides an example of registering a `JwtDecoder` bean, which is required for OIDC UserInfo and Client Registration endpoints. ```APIDOC ## Registering JwtDecoder Bean ### Description Registers a `JwtDecoder` bean using the `jwtDecoder` utility method, which is necessary for OIDC endpoints. ### Method N/A (Bean Definition) ### Endpoint N/A ### Parameters N/A ### Request Example ```java @Bean public JwtDecoder jwtDecoder(JWKSource jwkSource) { return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource); } ``` ### Response N/A ### Response Example N/A ``` -------------------------------- ### Configure RegisteredClient for Authorization Code Grant (Java) Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/core-model-components.adoc Example of configuring a RegisteredClient for the authorization_code grant flow. It specifies client ID, secret, authentication methods, redirect URI, scopes, and client settings like requiring an authorization consent. ```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(); ``` -------------------------------- ### Generate DPoP Proof JWT (Java) Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/protocol-endpoints.adoc Example code in Java demonstrating how to generate a DPoP Proof JWT using Nimbus JOSE+JWT library. It involves setting up JWK source, JWT encoder, and constructing the header and claims. ```java RSAKey rsaKey = ... JWKSource jwkSource = (jwkSelector, securityContext) -> jwkSelector .select(new JWKSet(rsaKey)); NimbusJwtEncoder jwtEncoder = new NimbusJwtEncoder(jwkSource); JwsHeader jwsHeader = JwsHeader.with(SignatureAlgorithm.RS256) .type("dpop+jwt") .jwk(rsaKey.toPublicJWK().toJSONObject()) .build(); JwtClaimsSet claims = JwtClaimsSet.builder() .issuedAt(Instant.now()) .claim("htm", "POST") .claim("htu", "https://server.example.com/oauth2/token") .id(UUID.randomUUID().toString()) .build(); Jwt dPoPProof = jwtEncoder.encode(JwtEncoderParameters.from(jwsHeader, claims)); ``` -------------------------------- ### Custom Authorization Server Settings Configuration Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/configuration-model.adoc Provides an example of how to customize AuthorizationServerSettings by overriding default URIs for protocol endpoints and setting a custom issuer URI. This allows for tailored configuration of the authorization server. ```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(); } ``` -------------------------------- ### JWT Access Token with Public Key Binding Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/protocol-endpoints.adoc Example of a JWT access token containing claims that confirm the binding to the DPoP proof public key. ```APIDOC ## JWT Access Token with Public Key Binding ### Description Demonstrates how a JWT access token can contain claims confirming its binding to a public key, typically via the `cnf` (confirmation) claim with a `jkt` (JWK SHA-256 Thumbprint) claim. ### Claims Example ```json { "sub":"user@example.com", "iss":"https://server.example.com", "nbf":1562262611, "exp":1562266216, "cnf": { "jkt":"CQMknzRoZ5YUi7vS58jck1q8TmZT8wiIiXrCN1Ny4VU" } } ``` ``` -------------------------------- ### POST /oauth2/introspect Source: https://context7.com/spring-projects/spring-authorization-server/llms.txt The Token Introspection endpoint allows resource servers to validate and get information about access tokens. ```APIDOC ## POST /oauth2/introspect ### Description Allows resource servers to validate and retrieve metadata about an access token. ### Method POST ### Endpoint /oauth2/introspect ### Parameters #### Request Body - **token** (string) - Required - The access token to introspect - **token_type_hint** (string) - Optional - Hint for the token type ### Request Example curl -X POST http://localhost:9000/oauth2/introspect -u resource-server-client:secret -H "Content-Type: application/x-www-form-urlencoded" -d "token=eyJraWQiOiI..." ### Response #### Success Response (200) - **active** (boolean) - Whether the token is currently active - **sub** (string) - Subject identifier - **scope** (string) - Scopes associated with the token #### Response Example { "active": true, "sub": "user", "aud": ["oidc-client"], "scope": "openid profile", "client_id": "oidc-client" } ``` -------------------------------- ### Enabling OpenID Connect 1.0 Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/configuration-model.adoc Shows how to enable OpenID Connect 1.0 by initializing the `OidcConfigurer` within the security filter chain. ```APIDOC ## Enabling OpenID Connect 1.0 ### Description Enables OpenID Connect 1.0 support by configuring the `OidcConfigurer`. ### Method N/A (Configuration within SecurityFilterChain) ### Endpoint N/A ### Parameters N/A ### Request Example ```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(); } ``` ### Response N/A ### Response Example N/A ``` -------------------------------- ### GET /oauth2/authorize Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/nav.adoc The Authorization Endpoint is used by the client to obtain authorization from the resource owner via user-agent redirection. ```APIDOC ## GET /oauth2/authorize ### Description Initiates the OAuth 2.0 authorization code flow or implicit flow to obtain an authorization grant. ### Method GET ### Endpoint /oauth2/authorize ### Parameters #### Query Parameters - **response_type** (string) - Required - The type of response the client expects (e.g., code). - **client_id** (string) - Required - The unique identifier for the client application. - **redirect_uri** (string) - Optional - The URI to which the response will be sent. - **scope** (string) - Optional - The scope of the access request. - **state** (string) - Recommended - An opaque value used to maintain state between the request and callback. ### Request Example GET /oauth2/authorize?response_type=code&client_id=my-client&redirect_uri=https://client.com/callback&scope=openid ### Response #### Success Response (302) - **Location** (header) - Redirects the user-agent to the redirect_uri with an authorization code. ``` -------------------------------- ### Configure Google OAuth Client in application.yml Source: https://github.com/spring-projects/spring-authorization-server/blob/main/samples/README.adoc YAML configuration for setting up Google as an OAuth 2.0 provider. ```yaml spring: security: oauth2: client: registration: <1> google-idp: <2> provider: google client-id: google-client-id client-secret: google-client-secret ``` -------------------------------- ### GET /oauth2/authorize Source: https://context7.com/spring-projects/spring-authorization-server/llms.txt The Authorization endpoint handles user authentication and authorization consent for redirect-based flows like Authorization Code. ```APIDOC ## GET /oauth2/authorize ### Description Handles user authentication and authorization consent for redirect-based flows. ### Method GET ### Endpoint /oauth2/authorize ### Parameters #### Query Parameters - **response_type** (string) - Required - Must be 'code' - **client_id** (string) - Required - The client identifier - **scope** (string) - Optional - Requested scopes - **redirect_uri** (string) - Required - The callback URL - **state** (string) - Recommended - CSRF protection token - **code_challenge** (string) - Optional - PKCE challenge - **code_challenge_method** (string) - Optional - PKCE method (S256) ### Request Example GET http://localhost:9000/oauth2/authorize?response_type=code&client_id=oidc-client&scope=openid%20profile&redirect_uri=http://127.0.0.1:8080/login/oauth2/code/oidc-client&state=xyz&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&code_challenge_method=S256 ### Response #### Success Response (302) - **Location** (header) - Redirects to the client's redirect_uri with a code or error. ``` -------------------------------- ### Implementing and Configuring OAuth2TokenCustomizer Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/core-model-components.adoc Illustrates how to create an OAuth2TokenCustomizer bean to modify token claims and how to inject it into an OAuth2AccessTokenGenerator. ```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 accessTokenCustomizer() { return context -> { OAuth2TokenClaimsSet.Builder claims = context.getClaims(); // Customize claims }; } ``` -------------------------------- ### Apply Minimal Default Configuration with OAuth2AuthorizationServerConfiguration Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/configuration-model.adoc Demonstrates how to use OAuth2AuthorizationServerConfiguration to apply the minimal default configuration for an OAuth 2.0 authorization server. This includes setting up a RegisteredClientRepository and a JWKSource. ```java @Configuration @Import(OAuth2AuthorizationServerConfiguration.class) public class AuthorizationServerConfig { @Bean public RegisteredClientRepository registeredClientRepository() { List registrations = ... return new InMemoryRegisteredClientRepository(registrations); } @Bean public JWKSource jwkSource() { RSAKey rsaKey = ... JWKSet jwkSet = new JWKSet(rsaKey); return (jwkSelector, securityContext) -> jwkSelector.select(jwkSet); } } ``` -------------------------------- ### Default Configuration with OAuth2 Authorization Server Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/configuration-model.adoc Demonstrates how to apply the minimal default configuration for an OAuth2 authorization server using `OAuth2AuthorizationServerConfiguration`. ```APIDOC ## Default Configuration ### Description Provides the minimal default configuration for an OAuth2 authorization server using `OAuth2AuthorizationServerConfiguration`. ### Method N/A (Configuration Class) ### Endpoint N/A ### Parameters N/A ### Request Example ```java @Configuration @Import(OAuth2AuthorizationServerConfiguration.class) public class AuthorizationServerConfig { @Bean public RegisteredClientRepository registeredClientRepository() { // ... setup RegisteredClientRepository return new InMemoryRegisteredClientRepository(registrations); } @Bean public JWKSource jwkSource() { // ... setup JWKSource return (jwkSelector, securityContext) -> jwkSelector.select(jwkSet); } } ``` ### Response N/A (Configuration applies defaults) ### Response Example N/A ``` -------------------------------- ### Configure GitHub OAuth Client in application.yml Source: https://github.com/spring-projects/spring-authorization-server/blob/main/samples/README.adoc YAML configuration for setting up GitHub as an OAuth 2.0 provider. ```yaml spring: security: oauth2: client: registration: <1> github-idp: <2> provider: github client-id: github-client-id client-secret: github-client-secret ``` -------------------------------- ### GET /.well-known/oauth-authorization-server Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/overview.adoc The Authorization Server Metadata Endpoint provides configuration details about the authorization server, including supported scopes, grant types, and endpoint locations. ```APIDOC ## GET /.well-known/oauth-authorization-server ### Description Returns the metadata configuration for the authorization server. ### Method GET ### Endpoint /.well-known/oauth-authorization-server ### Response #### Success Response (200) - **issuer** (string) - The URL of the authorization server. - **authorization_endpoint** (string) - The URL of the authorization endpoint. - **token_endpoint** (string) - The URL of the token endpoint. - **jwks_uri** (string) - The URL of the JWK Set endpoint. #### Response Example { "issuer": "https://auth.example.com", "authorization_endpoint": "https://auth.example.com/oauth2/authorize", "token_endpoint": "https://auth.example.com/oauth2/token", "jwks_uri": "https://auth.example.com/oauth2/jwks" } ``` -------------------------------- ### Apply Apache License Header to Java Files Source: https://github.com/spring-projects/spring-authorization-server/blob/main/CONTRIBUTING.adoc This snippet demonstrates the standard Apache 2.0 license header required for all new Java source files in the project. It ensures proper legal attribution and compliance with the project's licensing model. ```java /* * Copyright 2020-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ ``` -------------------------------- ### Configure OAuth2AuthorizationService Bean Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/core-model-components.adoc Registers an OAuth2AuthorizationService bean to handle the storage and retrieval of authorization instances. The example demonstrates using the InMemory implementation, suitable for development environments. ```java @Bean public OAuth2AuthorizationService authorizationService() { return new InMemoryOAuth2AuthorizationService(); } ``` -------------------------------- ### Configure OAuth2 Token Revocation Endpoint Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/protocol-endpoints.adoc Demonstrates the initial setup for customizing the OAuth2 Token Revocation endpoint using the OAuth2TokenRevocationEndpointConfigurer within the authorization server configuration. ```java @Bean public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception { OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = OAuth2AuthorizationServerConfigurer.authorizationServer(); http .securityMatcher(authorizationServerConfigurer.getEndpointsMatcher()) .with(authorizationServerConfigurer, (authorizationServer) -> authorizationServer .tokenRevocationEndpoint(tokenRevocationEndpoint -> tokenRevocationEndpoint ) ); return http.build(); } ``` -------------------------------- ### Add Spring Boot Starter Dependency Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/getting-started.adoc Configures the Spring Boot starter for the authorization server in your project build file. This is the recommended approach for Spring Boot applications. ```xml org.springframework.boot spring-boot-starter-oauth2-authorization-server ``` ```gradle implementation "org.springframework.boot:spring-boot-starter-oauth2-authorization-server" ``` -------------------------------- ### Implement TenantPerIssuerComponentRegistry Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/guides/how-to-multitenancy.adoc Creates a registry to manage and retrieve concrete component implementations based on the issuer identifier, supporting both static and dynamic tenant registration. ```java include::{examples-dir}/main/java/sample/multitenancy/TenantPerIssuerComponentRegistry.java[] ``` -------------------------------- ### GET /userinfo Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/protocol-endpoints.adoc The OpenID Connect 1.0 UserInfo endpoint is an OAuth2 protected resource that returns claims about the authenticated user. It requires a valid access token provided as a bearer token. ```APIDOC ## GET /userinfo ### Description Returns claims about the authenticated user based on the scopes requested during authorization. This endpoint is protected and requires a valid OAuth2 access token. ### Method GET ### Endpoint /userinfo ### Parameters #### Header Parameters - **Authorization** (string) - Required - Bearer ### Request Example GET /userinfo HTTP/1.1 Host: auth-server.example.com Authorization: Bearer ### Response #### Success Response (200) - **sub** (string) - Subject identifier - **name** (string) - Full name - **email** (string) - Email address #### Response Example { "sub": "248289761001", "name": "Jane Doe", "email": "jane.doe@example.com" } ``` -------------------------------- ### Register Tenants Dynamically Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/guides/how-to-multitenancy.adoc A Spring service pattern for managing dynamic tenant registration at runtime. This approach avoids static @Bean definitions when the number of tenants is unknown at startup. ```java @Service public class TenantService { public void addTenant(String tenantId, DataSource dataSource) { // Logic to register the new tenant's data source and associated components // at runtime without requiring a restart or static bean configuration. } } ``` -------------------------------- ### GET /oauth2/authorize Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/protocol-endpoints.adoc The OAuth2 Authorization endpoint is used to initiate the authorization flow. It can be customized via the OAuth2AuthorizationEndpointConfigurer to handle specific request converters, authentication providers, and custom consent pages. ```APIDOC ## GET /oauth2/authorize ### Description Initiates the OAuth2 authorization request flow. This endpoint processes incoming authorization requests and handles user consent. ### Method GET ### Endpoint /oauth2/authorize ### Parameters #### Query Parameters - **response_type** (string) - Required - The type of response requested (e.g., code). - **client_id** (string) - Required - The client identifier. - **redirect_uri** (string) - Optional - The URI to redirect to after authorization. - **scope** (string) - Optional - The requested scopes. - **state** (string) - Optional - An opaque value used to maintain state between the request and callback. ### Request Example GET /oauth2/authorize?response_type=code&client_id=my-client&redirect_uri=http://localhost:8080/callback&scope=openid&state=xyz ### Response #### Success Response (302) - **Location** (string) - Redirects to the client redirect URI with an authorization code or to the consent page. #### Error Response (400/401) - **error** (string) - The error code. - **error_description** (string) - A human-readable description of the error. ``` -------------------------------- ### Dynamically Register a Client Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/guides/how-to-dynamic-client-registration.adoc This Java code snippet illustrates how to use an obtained access token to dynamically register a new client with the Spring Authorization Server. It shows the process of creating a client registrar and initiating the registration request. ```java import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.client.registration.ClientRegistrar; import org.springframework.security.oauth2.core.ClientAuthenticationMethod; import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames; import org.springframework.security.oauth2.core.oidc.OidcScopes; import org.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames; import org.springframework.security.oauth2.core.oidc.registration.ClientRegistrationRequest; import org.springframework.security.oauth2.core.oidc.registration.ClientRegistrationResponse; import org.springframework.web.reactive.function.client.WebClient; import java.util.Set; public class ClientRegistrar { private final WebClient clientRegistrationWebClient; public ClientRegistrar(WebClient clientRegistrationWebClient) { this.clientRegistrationWebClient = clientRegistrationWebClient; } public ClientRegistrationResponse registerClient(String accessToken) { // Define the client registration request ClientRegistrationRequest registrationRequest = new ClientRegistrationRequest( ClientRegistration.withRegistrationId("my-dynamic-client") .clientId("my-dynamic-client-id") .clientName("My Dynamic Client") .clientSecret("my-dynamic-secret") .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_POST) .authorizationGrantType(new org.springframework.security.oauth2.core.AuthorizationGrantType("authorization_code")) .redirectUri("http://localhost:8080/authorized") .scope(OidcScopes.OPENID) .scope(OidcScopes.PROFILE) .build() ); // Send the registration request return clientRegistrationWebClient .post() .uri("/oauth2/register") // Assuming the registration endpoint is at /oauth2/register .header("Authorization", "Bearer " + accessToken) .bodyValue(registrationRequest) .retrieve() .bodyToMono(ClientRegistrationResponse.class) .block(); } } ``` -------------------------------- ### Enable OpenID Connect 1.0 with OAuth2AuthorizationServerConfigurer Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/configuration-model.adoc Shows how to enable OpenID Connect 1.0 by initializing the OidcConfigurer within the OAuth2AuthorizationServerConfigurer. This adds OIDC-specific endpoints like the Provider Configuration, Logout, and UserInfo endpoints. ```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(); } ``` -------------------------------- ### Configure and Use Token Introspection Endpoint Source: https://context7.com/spring-projects/spring-authorization-server/llms.txt Configures the token introspection endpoint to allow resource servers to validate tokens. Includes a cURL example for sending an introspection request and the expected JSON response for an active token. ```java @Bean public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception { OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = OAuth2AuthorizationServerConfigurer.authorizationServer(); http .securityMatcher(authorizationServerConfigurer.getEndpointsMatcher()) .with(authorizationServerConfigurer, (authorizationServer) -> authorizationServer .tokenIntrospectionEndpoint(tokenIntrospectionEndpoint -> tokenIntrospectionEndpoint .introspectionRequestConverter(introspectionRequestConverter) .authenticationProvider(authenticationProvider) .introspectionResponseHandler(introspectionResponseHandler) .errorResponseHandler(errorResponseHandler) ) ); return http.build(); } ``` ```bash curl -X POST http://localhost:9000/oauth2/introspect \ -u resource-server-client:secret \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "token=eyJraWQiOiI..." ``` -------------------------------- ### Register JwtDecoder Bean for OIDC Endpoints Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/configuration-model.adoc Provides an example of registering a JwtDecoder bean, which is required for OpenID Connect 1.0 UserInfo and Client Registration endpoints. This utilizes the convenience static utility method jwtDecoder from OAuth2AuthorizationServerConfiguration. ```java @Bean public JwtDecoder jwtDecoder(JWKSource jwkSource) { return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource); } ``` -------------------------------- ### Customize JWT Tokens with OAuth2TokenCustomizer Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/core-model-components.adoc Demonstrates how to implement an OAuth2TokenCustomizer to modify JWT headers and claims. It also shows how to configure a DelegatingOAuth2TokenGenerator with a custom JWT generator. ```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 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 } }; } ``` -------------------------------- ### RegisteredClient Overview Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/core-model-components.adoc Explains the concept of a RegisteredClient, its role in OAuth 2.0, and its configuration. ```APIDOC ## RegisteredClient ### Description A `RegisteredClient` represents a client registered with the authorization server. It is essential for initiating authorization grant flows like `authorization_code` or `client_credentials`. Clients are assigned a unique identifier, an optional secret, and metadata such as redirect URIs. ### Method N/A (Conceptual Model) ### Endpoint N/A (Conceptual Model) ### Parameters N/A ### Request Example ```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 NoOpPasswordEncoder. ### Response N/A (Conceptual Model) ### Response Example N/A ``` -------------------------------- ### JWT Access Token with Public Key Confirmation (JSON) Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/protocol-endpoints.adoc Example of claims within a JWT access token that is DPoP-bound. It includes the 'cnf' claim containing the 'jkt' claim, which is the JWK SHA-256 Thumbprint of the DPoP proof's public key. ```json { "sub":"user@example.com", "iss":"https://server.example.com", "nbf":1562262611, "exp":1562266216, "cnf": { "jkt":"CQMknzRoZ5YUi7vS58jck1q8TmZT8wiIiXrCN1Ny4VU" } } ``` -------------------------------- ### Customize JWT User Info Mapper in Java Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/guides/how-to-userinfo.adoc This Java code configures a custom user info mapper for JWTs in Spring Authorization Server. It allows for dynamic population of claims based on external data sources. This example focuses on customizing access token claims. ```java include::{examples-dir}/main/java/sample/userinfo/jwt/JwtTokenCustomizerConfig.java[] ``` -------------------------------- ### Base64 Encode Client Credentials Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/guides/how-to-dynamic-client-registration.adoc This console command demonstrates how to base64 encode client credentials in the format ':' for use in the Authorization header of an access token request. ```console echo -n "registrar-client:secret" | base64 ``` -------------------------------- ### Add Authorities as Custom Claims to JWT Access Tokens (Java) Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/guides/how-to-custom-claims-authorities.adoc This example demonstrates how to add resource owner authorities to a JWT access token. It defines a sample user with roles and customizes the JWT by extracting these roles from the Principal and adding them as a 'roles' claim. This requires an OAuth2TokenCustomizer bean. ```java import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.oauth2.jwt.JwtClaimsSet; import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext; import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenCustomizer; import java.util.HashSet; import java.util.Set; import java.util.stream.Collectors; @Configuration(proxyBeanMethods = false) public class CustomClaimsWithAuthoritiesConfiguration { @Bean public OAuth2TokenCustomizer jwtCustomizer() { return context -> { // Customize claims JwtClaimsSet.Builder claims = context.getClaims(); Set roles = new HashSet<>(); // Example: Extract roles from Principal Object principal = context.getPrincipal().getPrincipal(); if (principal instanceof User) { roles = ((User) principal).getAuthorities().stream() .map(GrantedAuthority::getAuthority) .map(authority -> authority.replace("ROLE_", "")) .collect(Collectors.toSet()); } // Add custom claim 'roles' claims.claim("roles", roles); }; } // Sample UserDetailsService for demonstration @Bean public UserDetailsService userDetailsService() { UserDetails user = User.withUsername("user1") .password("password") .authorities("ROLE_USER", "ROLE_ADMIN") .build(); return new org.springframework.security.provisioning.InMemoryUserDetailsManager(user); } } ``` -------------------------------- ### Configure OAuth2 Token Endpoint with Custom Grant Type Components Source: https://github.com/spring-projects/spring-authorization-server/blob/main/docs/modules/ROOT/pages/guides/how-to-ext-grant-type.adoc Configures the OAuth2 Token endpoint by adding custom AuthenticationConverter and AuthenticationProvider. This setup ensures that the authorization server can process requests for the newly implemented extension grant type. It involves registering these components within the security configuration. ```java package sample.extgrant; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configurers.oauth2.server.authorization.OAuth2AuthorizationServerConfigurer; import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer; import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.util.matcher.RequestMatcher; @EnableWebSecurity @Configuration public class SecurityConfig { @Bean public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception { OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = new OAuth2AuthorizationServerConfigurer(); // Configure custom AuthenticationConverter and AuthenticationProvider authorizationServerConfigurer .tokenEndpoint(tokenEndpoint -> tokenEndpoint .authenticationConverter(new CustomCodeGrantAuthenticationConverter()) .authenticationProvider(customCodeGrantAuthenticationProvider()) ); RequestMatcher endpointsMatcher = authorizationServerConfigurer .getEndpointsMatcher(); http.securityMatcher(endpointsMatcher) .authorizeRequests(authorizeRequests -> authorizeRequests.anyRequest().authenticated()) .csrf(csrf -> csrf.ignoringAntMatchers("/oauth2/token")) // Disable CSRF for token endpoint .apply(authorizationServerConfigurer); return http.build(); } @Bean public CustomCodeGrantAuthenticationProvider customCodeGrantAuthenticationProvider() { // Requires RegisteredClientRepository and OAuth2TokenGenerator beans RegisteredClientRepository registeredClientRepository = null; // Replace with actual bean OAuth2TokenGenerator tokenGenerator = null; // Replace with actual bean OAuth2AuthorizationService authorizationService = null; // Replace with actual bean return new CustomCodeGrantAuthenticationProvider(tokenGenerator, authorizationService); } // Other necessary beans like RegisteredClientRepository, OAuth2TokenGenerator, OAuth2AuthorizationService would be defined here. } ```