Lab 7: SpringBoot REST Service Protected Using Keycloak Authorization Services

In this lab we are going to see how to protect a SpringBoot REST service using Keycloak Authorization Services.

Learning Targets

This lab tries to focus on the authorization features provided by Keycloak Authorization Services, where access to resources depends on users profile.

In this application, there are three paths protected by specific permissions in Keycloak:

  • /unsecured, access to this path is open to everyone

  • /user where access to this page is restricted to users with ADMIN role

  • /admin where any user with a role USER is allowed to access this path

By the end of this Lab, you will learn :

  • How to secure APIs using stateless JWT token

  • Adding a basic authorization layer to protect

  • Writing unit test for your code

Start the lab

When running the initial version of this application, all APIs are reachable without authentication :

Open Access to APIs

Step 1 : Adding dependecies

So let's start by adding the following dependencies :

  • First, we need to specify the keycloak version :

  • Add the Adapter BOM dependency:

  • Adapter Installation : The Keycloak Spring Boot adapter takes advantage of Spring Boot’s autoconfiguration so all you need to do is add the Keycloak Spring Boot starter to your project. To add it using Maven, add the following to your dependencies:

Step 2 : Adding Keycloak configuration

We can configure the realm for the Spring Boot Keycloak adapter via the normal Spring Boot configuration. For example:

We are going to use a bearer token for authentication (so no need to set-up the client and secret id) :

Step 3 : Adding security constraints :

In the same spring boot configuration file, add the following in order to secure access to our APIs :

Step 4 : Java configuration

Keycloak provides a KeycloakWebSecurityConfigurerAdapter as a convenient base class for creating a WebSecurityConfigurer instance. The implementation allows customization by overriding methods. While its use is not required, it greatly simplifies your security context configuration :

Let's add this to our code :

  • @ConditionalOnProperty(name = "keycloak.enabled", havingValue = "true", matchIfMissing = true) : make it easy to enable/disable our keycloak set-up

  • The @KeycloakConfiguration annotation is a metadata annotion that defines all annotations that are needed to integrate Keycloak in Spring Security. If you have a complexe Spring Security setup you can simply have a look ath the annotations of the @KeycloakConfiguration annotation and create your own custom meta annotation or just use specific Spring annotations for the Keycloak adapter.

Step 5 : Naming Security Roles

Spring Security, when using role-based authentication, requires that role names start with ROLE_. For example, an administrator role must be declared in Keycloak as ROLE_ADMIN or similar, not simply ADMIN.

The class org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider supports an optional org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper which can be used to map roles coming from Keycloak to roles recognized by Spring Security. Use, for example, org.springframework.security.core.authority.mapping.SimpleAuthorityMapper to insert the ROLE_ prefix and convert the role name to upper case. The class is part of Spring Security Core module.

Step 6 : Using Spring Boot Configuration

By Default, the Spring Security Adapter looks for a keycloak.json configuration file. You can make sure it looks at the configuration provided by the Spring Boot Adapter by adding this bean :

Note : there is an issuearrow-up-right with Keycloak for versions prior to 9, where you need to use a KeycloakSpringBootConfigResolver instead of this bean :

Sample error message :

A work around will be to use the following code :

Step 7 : Define Spring BSecurity Matchers

This where we define how and which APIs we want to protect :

Let's do some tests :

Before testing our APIs, let's import the Realm configuration file related to this lab :

realm-export.jsonarrow-up-right

Then, create 2 users :

  • User ineat-admin / password with ADMIN role associated

  • User ineat-user / password With USER role associated

Then use the following postman collectionarrow-up-right to test our APIs

Last updated