Spring boot Oauth2 Resource Server — Kotlin

Karanbir Singh
3 min readApr 15, 2020

--

Agenda

Spring/ Spring Boot recently had changed the support for oauth2 and have provided resource server based starter dependency spring-boot-starter-oauth2-resource-server.

This means they are providing some special support for configuring your Spring boot based project to act as a resource server out of the box.

This one is just a basic code and has following Assumptions/ Notes to start with:-

  1. One should be knowing the basics of Spring boot as we are going to use spring-boot-starter-oauth2-resource-server based setup.
  2. I could have used Java for this? Yes one may, But just wanted to smell some fragrance of Kotlin. One may easily be able to get the Java based working within no time. For java use the branch java here
  3. Using JDK 11.
  4. Have basic knowledge of Oauth2, JWT, Spring Boot, Spring Security, Kotlin/Java etc.
  5. The Authorization Server implementation is out of context for this article, but one may contact/ message me for further understanding around that.
  6. The Authorization Server will create JWT type access token and payload will match like below(for different format customization will be required):-

7. The main flow is like below, and our focus would be mainly on the 4th one i.e. Resource Server :-

Code

The link to the code repository for Kotlin is — https://github.com/krnbr/demo-resource-server

And for Java it is — https://github.com/krnbr/demo-resource-server/tree/java

Details

  1. To start with you can see we added two main dependencies in the pom.xml

2. In the spring application.properties we added below properties related to the JWT based authorization

spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8080
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=http://localhost:8080/.well-known/jwks.json

issuer-uri is for setting the issuer that we will receive in the JWT payload
jwk-set-uri is the JWKS url

3. The project has only one url as of now and it is GET/api/v1/test while other are related to the actuator available at /manage/* and /api/v1/test is protected and annotated with the annotation @PreAuthorize as below:-

@PreAuthorize("hasAuthority('SCOPE_system')")

Above annotation will require the request to have a scope system in access token’s JWT payload as below:-

"scopes": "system",

scopes above can be space separated like below example:-

"scopes": "system messages:read",

4. Other urls available are actuator urls

/manage/info & /manage/health are available to all

all other /manage/* urls will require the request to have an access token with scope of admin

5. CustomBearerTokenServerAccessDeniedHandler is a custom access denied handler & CustomBearerTokenServerAuthenticationEntryPoint is a custom authentication entry point. They were brought in to support the return of JSON based error response for few scenarios.

6. HasScope is a custom ReactiveAuthorizationManager to support the kind of access management feature as below(see the bold HasScope):-

// health and info url's will be open(permitted to all) others will be checked for authorization
.matchers(EndpointRequest.to(HealthEndpoint::class.java, InfoEndpoint::class.java)).permitAll()
// all other endpoints will require the scope to be "admin"
.matchers(EndpointRequest.toAnyEndpoint()).access(HasScope("admin"))

7. ApplicationExceptionHandler is the exception handler to handle various exceptions in the application

For further extended customization of the JWKS endpoint using mutual TLS, you can go through the link here.

Feel free to contact for any issues.

You can connect with me on LinkedIn here for further help.

--

--

Karanbir Singh
Karanbir Singh

Written by Karanbir Singh

API developer + Web Application developer + Devops Engineer = Full Stack Developer

No responses yet