Securing a Spring Boot Application with Keycloak

In this article, I’m going to show you how to secure a Spring Boot application using Keycloak.

Securing Spring Boot with Keycloak - ThomasVItale.com

Before doing that, I’d like to briefly recall what I’ve done so far.

First, I highlighted the main features of Keycloak used in this series and explained how to install and boot the Keycloak server.

Then, I set Keycloak with some basic configurations to use it for securing a web application (providing it with authentication and authorisation).

In this article, I’ll talk about how to:

    1. Create a client in Keycloak;
    2. Set up the Spring Boot application;
    3. Define the application resources;
    4. Add access policies based on user roles.

You can check out the full source code of the demo project I’m going to build on GitHub.

Let’s get started!

Create a Client in Keycloak

The first step in securing a web application with Keycloak is creating a client. But what is a client?

“Clients are entities that can request authentication of a user.”

In this context, a client represents a web application that wants to use Keycloak to authenticate and authorise users.

To create a new client, go to Clients and then click Create.

Keycloak screen for Clients
Keycloak Clients Page

Fill in the form to add a new client by providing the following information:

  • Client ID: the string used to identify the client, I’ve chosen app-client;
  • Client Protocol: I want to use OpenID Connect (OIDC), so I’ve chosen openid-connect;
  • Root URL: the root URL of your web application, for me it’s http://localhost:8080.

Keycloak window to create a new client

Once you create the client, a new page opens with further fields to configure it. Make sure you set the following options in this way:

  • Access Type: public;
  • Enabled: ON;
  • Standard Flow Enabled: ON.

The Access Type option defines the type of the client. As explained in the documentation, “Public access type is for client-side clients that need to perform a browser login”, that is exactly what I want.

Since the access to the client will be public, for security reasons, it’s essential that you restrict it by setting the redirect URIs correctly. Keycloak automatically generates them from the Root URL, but you can add more of them. The more specific you are, the better.

Moreover, it’s critical to enable HTTPS on your application to encrypt the data exchanged with the server and prevent third-parties from intercept sensitive data.

The Enabled option allows turning on and off the client for requesting authentication.

The Standard Flow Enabled property is used to activate the Authorization Code Flow as defined in the OIDC standard. It’s the recommended protocol to use for authenticating and authorising browser-based applications.

I think it could be helpful illustrating the flow from the user point of view:

  1. A user visits the application on a browser and tries to access a protected resource;
  2. The application redirects the user to the Keycloak login page;
  3. The user enters their own username and password;
  4. Keycloak authenticates the user;
  5. If the authentication succeeds, Keycloak will redirect the user to the protected resource of the application.

In the background, Keycloak provides the application with two tokens as defined by the OIDC protocol:

  • An Identity Token, which contains information about the logged user such as the username and the email.
  • An Access Token, digitally signed by the realm, which contains access data such as the roles assigned to the logged user.

You can also customise the look and feel of the Keycloak login page thanks to the Themes. I won’t cover that. Instead, in a future article, I’ll show you how to use a login form internal to your application (both with Thymeleaf and AngularJS).

That’s it. You have just created a client that you can use to authenticate the users visiting your application.

Without further ado, let’s start setting up the Spring Boot application.

Set up the Spring Boot application

Time to code!

You can make your application interact with Keycloak very easily thanks to the so-called Client Adapters.

“Keycloak client adapters are libraries that makes it very easy to secure applications and services with Keycloak.”

For this project, you need the Spring Boot Adapter

If you’re using Gradle, you can add the following dependency to your build.gradle file:

compile "org.keycloak:keycloak-spring-boot-starter:3.3.0.Final"
view raw build.gradle hosted with ❤ by GitHub

while if you’re using Maven, you can add the following dependency to your pom.xml file:

<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-starter</artifactId>
<version>3.3.0.Final</version>
</dependency>
view raw pom.xml hosted with ❤ by GitHub

The next step is configuring your Spring Boot application to use Keycloak. Open the application.properties file and write the following configuration:

keycloak.realm=Demo
keycloak.resource=app-client
keycloak.auth-server-url=http://localhost:8180/auth
keycloak.ssl-required=external
keycloak.public-client=true
keycloak.principal-attribute=preferred_username

Let’s quickly go over each property:

  • keycloak.realm: the name of the realm, required;
  • keycloak.resource: the client-id of the application, required;
  • keycloak.auth-server-url: the base URL of the Keycloak server, required;
  • keycloak.ssl-required: establishes if communications with the Keycloak server must happen over HTTPS. Here, it’s just required for external requests (default value), but in production, you should set it to all. Optional;
  • keycloak.public-client: prevents the application from sending credentials to the Keycloak server (true is the default value). You want to set it to false whenever you use confidential clients instead of public. Optional;
  • keycloak.principal-attribute: this is an extra property that allows retrieving the username of the currently logged user from the Principal object. I’m going to use that to show the username in the front-end.

Define the application resources

To demonstrate how Keycloak can handle authentication and authorisation for a Spring Boot application, I’ll define three resources:

  • /index will be freely accessible;
  • /user will be accessible only by users with normal privileges (User role);
  • /admin will be accessible only by users with administrative privileges (Admin role).

The last two resources require the users to be authenticated and have the proper role. It’s also helpful adding a fourth resource for logging out. Here’s my code:

@Controller
public class AppController {
@RequestMapping(value = "/", method = RequestMethod.GET)
public String getHome() {
return "index";
}
@RequestMapping(value = "/user", method = RequestMethod.GET)
public String getUser(Principal principal, Model model) {
model.addAttribute("user", principal.getName());
return "user";
}
@RequestMapping(value = "/admin", method = RequestMethod.GET)
public String getAdmin(Principal principal, Model model) {
model.addAttribute("admin", principal.getName());
return "admin";
}
@RequestMapping(value = "/logout", method = RequestMethod.GET)
public String handleLogout(HttpServletRequest request) throws ServletException {
request.logout();
return "redirect:/";
}
}
view raw AppController.java hosted with ❤ by GitHub

This is a normal Controller as used in every Spring MVC application; it should be very straightforward.

As a template engine, I have chosen Thymeleaf. I have created a template for each resource with just a title containing the username of the currently logged user (if any), a paragraph explaining the privileges needed to access that resource and basic navigation. You can check out the full source code of this demo project on GitHub.

Add access policies based on user roles

By now, you should be able to run the application and navigate it freely through a browser. Even though you have correctly configured and integrated Keycloak into your application, you haven’t defined yet which resources you want to protect and which privileges a user needs to access them.

It’s the perfect job for Spring Security, but I’ll explain that in the next article. Here, I’m going to exploit the Spring Boot configuration.

Add the following to the application.properties file:

keycloak.securityConstraints[0].authRoles[0] = User
keycloak.securityConstraints[0].authRoles[1] = Admin
keycloak.securityConstraints[0].securityCollections[0].name = user resource
keycloak.securityConstraints[0].securityCollections[0].patterns[0] = /user
keycloak.securityConstraints[1].authRoles[0] = Admin
keycloak.securityConstraints[1].securityCollections[0].name = admin resource
keycloak.securityConstraints[1].securityCollections[0].patterns[0] = /admin

I have defined two security constraints, one for each resource to protect. For each security constraint, I have set the authorisation roles that a user must have to access a protected resource. Then, I have specified a name and a pattern for the URL associated with the resource.

Actually, the second row is not needed. Since I defined the Admin role as composite, it automatically has User privileges as well.

When a user tries to access a protected resource, they will be redirected to Keycloak that authenticates them. If the authentication succeeds, Keycloak will redirect the user to the application.

At this point, the application will have received by Keycloak an Access Token containing all the information relevant to the authorisation of the user, including the user roles. If they don’t have the role needed to access the resource, Spring Boot will show an error page.

Conclusion

In this article, I’ve explained how to create a client in Keycloak and how to use it as a resource to get authentication and authorisation services for a Spring Boot application.

The essential parts have been the use of the Spring Boot Adapter, and the Keycloak configuration and the access policies definition in the application.properties.

You can check out the full source code of the demo project on GitHub.

Next time, I’ll write about using Spring Security to have more control while still relying on Keycloak. I’ll also go over the information associated with each user and how it can be retrieved from the Identity Token.

Have you secured your application using Keycloak? Leave a comment and let me know about it!

Keycloak Series

Leave a Reply

Your email address will not be published. Required fields are marked *