Introduction

OAuth simplifies user authentication by allowing third-party applications to access user data without the need to share sensitive credentials, such as username and password. Initially, the user authenticates with the service provider. Following authentication, the service provider seeks the user’s consent to authorize the access request. Once authorized, the service provider issues an access token that can be used to access resources in the resource server.

OAuth2 Flow

We will transform the backend of Tabunganku into a resource server that connects to the Keycloak to validate authentication token sent by the frontend. To achieve this, we have to modify the existing backend project.

Implementation

We add several libraries to our Spring Boot project: spring-boot-starter-security, spring-boot-starter-oauth2-resource-server, and spring-addons-starter-oidc. spring-addons is an external library that simplifies integration process with Keycloak. In this project, we are using version 7.2.0 of spring-addons.

Application YML File

We include a new configuration for Spring addons library in the application.yml:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
com:
    c4-soft:
        springaddons:
            oidc:
                ops:
                    - iss: ${keycloak-issuer}
                      username-claim: preferred_username
                      authorities:
                          - path: $.realm_access.roles
                          - path: $.resource_access.*.roles
                resourceserver:
                    permit-all:
                        - "/actuator/health/readiness"
                        - "/actuator/health/liveness"
                        - "/tabunganku-api-docs/**"
                        - "/tabunganku-documentation"
                        - "/swagger-ui/**"
                        - "/v3/api-docs/**"
                    cors:
                        - path: /**
                          allowed-origin-patterns: ${TABUNGAN_FE_URL}

ops section defines Keycloak’s realm URL, username, and authorities. iss indicates the entity issuing the authorization token. An example of a valid keycloak-issuer value is http://172.20.10.5:8180/realms/Tabungan. username-claim and authorities read values from the token to validate a user’s username and authorities.

resourceserver section has two sub sections: permit-all and cors. permit-all acts as a whitelist, allowing specific endpoints to be accessed without any restrictions, while cors defines the Cross-Origin Resource Sharing policy for endpoints. In the snippet above, I whitelist endpoints for health check and documentation and set a policy that requires all endpoints to be accessed from the TABUNGAN_FE_URL origin.

Configuration Class

We specify the authorization policy in a configuration class by using a post processor class from spring-addons library.

1
2
3
4
5
6
@Bean
ExpressionInterceptUrlRegistryPostProcessor expressionInterceptUrlRegistryPostProcessor() {
    return (AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry registry) -> registry
            .requestMatchers("/secured-route").hasRole("AUTHORIZED_PERSONNEL")
            .anyRequest().authenticated();
}

In this snippet, we see that the registry creates two policies. The first policy is to restrict access to the secured-route endpoint for a user with the AUTHORIZED_PERSONNEL role. Meanwhile, the other policy is to restrict access to all endpoints for authenticated users only, with exception for endpoints defined in the permit-all section in the application.yml file. Note the order of the policy written here; the most generic policy should be placed last.

Conclusion

Thanks to the spring-addons library, setting up a resource server becomes much easier. It provides a lot of flexibility out of the box without the need to deal with the complexity of Spring Security. Visit their GitHub repository (link provided below).

  • OAuth documentation by Oracle: link
  • Spring addons Github page: link
  • Tabunganku backend Github page: link