Spring Authorization Server

Spring%20Auth%20Server%20Docs 2088E9?logo=quickLook&logoColor=white Spring%20Boot%20Auth%20Server%20Docs 2088E9?logo=quickLook&logoColor=white Spring%20Auth%20Server%20API%20Docs DF7716?logo=devbox&logoColor=white

Maven Dependency

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-authorization-server</artifactId>
</dependency>

Getting Started

In the official documentation you can find example implementation of 🟢 SecurityConfig.

Example

@Bean
public RegisteredClientRepository registeredClientRepository() {
    RegisteredClient oidcClient = RegisteredClient.withId(UUID.randomUUID().toString())
            .clientId("oidc-client")
            .clientSecret("{noop}secret")
            .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
            .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
            .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
            .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
            .redirectUri("http://127.0.0.1:8080/login/oauth2/code/oidc-client")
            .redirectUri("http://127.0.0.1:8080/authorized")
            .scope(OidcScopes.OPENID)
            .scope(OidcScopes.PROFILE)
            .scope("message.read")
            .scope("message.write")
            .clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
            .build();

    return new InMemoryRegisteredClientRepository(oidcClient);
}

you can request JWT token in Postman in Authorization tab with OAuth 2.0 type by configuring new token:

and hitting Get New Access Token button.

🔴 InMemoryRegisteredClientRepository is recommended ONLY to be used during development/testing.

The encoded JWT Access Token looks like:

eyJraWQiOiJkNDkzYjc0Ni03NzhhLTQ5OWQtOWU1OS00ZDVmZWE4ZWFlYWIiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJvaWRjLWNsaWVudCIsImF1ZCI6Im9pZGMtY2xpZW50IiwibmJmIjoxNzI4MzMyMzY2LCJzY29wZSI6WyJtZXNzYWdlLnJlYWQiLCJtZXNzYWdlLndyaXRlIl0sImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6OTA5MCIsImV4cCI6MTcyODMzMjY2NiwiaWF0IjoxNzI4MzMyMzY2LCJqdGkiOiI4N2YxZmVmYy1lODEwLTQ4MGItYjUyMC03ZmFmNTI1MDdiZmIifQ.iR34FpFD-Ev4Haxs_hhqp_73b-AN5O0x-GpV7ji_jHVohg-jR7RiLHMC-EbYtUcpMnUSd-c4Zm8O7j_JMKUdShLlWxfVMb06YPa9Hz-Np0aaH26EcHCt-ydFFof0xri7HEfWOcs0N_Ba1YLwDpK2E2I1hDYgqF3HRlVyLgSobokYKEJFUIMtq3WJVxEbOqv0rm9R6ULL3YHsRghubQBLHrdmoQMpVDNczytC29s16DfMOmy_Ob7fMDzOo-NLEEPtADHlcPkhzl0nVumcfIQo7LPXU7ZHZm0Qav-c3c8kXfZLrRdOET3raZkxx1VRS9nPDARNqGr5wyNeSL-4MDp-jA

The decoded JWT Access Token looks like:

{
  "header":{
    "kid":"d493b746-778a-499d-9e59-4d5fea8eaeab",
    "alg":"RS256"
  },
  "payload":{
    "sub":"oidc-client",
    "aud":"oidc-client",
    "nbf":1728332366,
    "scope":[
      "message.read",
      "message.write"
    ],
    "iss":"http://localhost:9000",
    "exp":1728332666,
    "iat":1728332366,
    "jti":"87f1fefc-e810-480b-b520-7faf52507bfb"
  }
}

In Postman the Authorization header will be added to each request with value: Bearer eyJraWQiOiJkNDkzYjc0Ni03NzhhLTQ5OWQtOWU1OS00ZDVmZWE4ZWFlYWIiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJvaWRjLWNsaWVudCIsImF1ZCI6Im9pZGMtY2xpZW50IiwibmJmIjoxNzI4MzMyMzY2LCJzY29wZSI6WyJtZXNzYWdlLnJlYWQiLCJtZXNzYWdlLndyaXRlIl0sImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6OTA5MCIsImV4cCI6MTcyODMzMjY2NiwiaWF0IjoxNzI4MzMyMzY2LCJqdGkiOiI4N2YxZmVmYy1lODEwLTQ4MGItYjUyMC03ZmFmNTI1MDdiZmIifQ.iR34FpFD-Ev4Haxs_hhqp_73b-AN5O0x-GpV7ji_jHVohg-jR7RiLHMC-EbYtUcpMnUSd-c4Zm8O7j_JMKUdShLlWxfVMb06YPa9Hz-Np0aaH26EcHCt-ydFFof0xri7HEfWOcs0N_Ba1YLwDpK2E2I1hDYgqF3HRlVyLgSobokYKEJFUIMtq3WJVxEbOqv0rm9R6ULL3YHsRghubQBLHrdmoQMpVDNczytC29s16DfMOmy_Ob7fMDzOo-NLEEPtADHlcPkhzl0nVumcfIQo7LPXU7ZHZm0Qav-c3c8kXfZLrRdOET3raZkxx1VRS9nPDARNqGr5wyNeSL-4MDp-jA where after Bearer there is encoded JWT.

Customizing Authorization Server port

You can customize Authorization Server port with this property

server.port=9000

Customizing Authorization Server endpoints

You can find Authorization Server endpoints in 🔴 AuthorizationServerSettings.html#builder(). If you want to customize them, check official documentation.

Testing

An example how OAuth 2.0 with JWT support can be added to the test:

mockMvc.perform(get("/api/v1/resource")
            with(jwt().jwt(jwt -> jwt.claims(claims -> {
                    claims.put("scope", "message-read");
                    claims.put("scope", "message-write");
                }).subject("oidc-client").notBefore(Instant.now().minusSeconds(5L)))) (1)
            .accept(MediaType.APPLICATION_JSON))
    .andExpect(status().isOk())
    .andExpect(content().contentType(MediaType.APPLICATION_JSON))
    .andExpect(jsonPath("$.content.length()", is(3)));
1 This way we can add Authorization header to the request

If your test is annotated with @SpringBootTest, then you need to create 🔴 MockMvc like this:

MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(wac)
    .apply(springSecurity()) (1)
    .build();
1 Configure 🔴 MockMvc to use Spring Security

If your test is annotated with @WebMvcTest, then you need to import 🟢 SecurityConfig by annotating the test class with:

@Import(SecurityConfig.class)