Integrate Keycloak with Spring Boot


Years ago we had to expend much more time implementing the security of our enterprise applications, basically, I'm talking about Web application security. But nowadays there are some Identity management tools that can be used to make easier our lives.

What is an Identity management tool?

Simply it can be used as a security provider. We can delegate our security to a third party. It is just like hiring a security person or hiring a bodyguard. 

What is Keycloak?

This is one of the best tools that can be used as an authentication management tool. Actually, it is an identity provider. You can very easily integrate it into your Spring Boot applications and if you want you can integrate it with Spring Security also.

Advantages of Keycloak?
  • It is lightweight and fast.
  • Single sign-on
  • It uses standard protocols such as OAuth 2.0, OpenID, SAML 2.0...etc.
  • It can be managed easily. 
  • Very easy to use with Keycloak adapters.
  • Very easy to enable social logins.

Here I'm not going to explain more details about Security concerns. I just wanted to explain the integration of Keycloak with Spring Boot.

First of all, let's create a simple web application using Spring Boot. Go through the following link to get started with Spring Boot if you are new to Spring Boot.

http://www.javafoundation.xyz/2017/06/spring-boot-hello-world-project.html#.W77OhWgzZnK

Here I'm going to create a simple web application to demonstrate this. 

ReservationController.java

package com.app.api;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;

@Controller
public class ReservationController {

    @GetMapping("/")
    public String home(){
        return "index";
    }

    @GetMapping("/reservation")
    public String getReservations(){
        return "reservations";
    }

    @GetMapping("/logout")
    public String logout(HttpServletRequest request) throws ServletException {
        request.logout();
        return "index";
    }
}


index.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Home</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>

    <h1>Home page</h1>
    <a href="/reservation">My Reservations</a>
</body>
</html>


reservations.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Reservations</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>

    <h2>Reservations page</h2>

    <a href="/logout">Logout</a>

</body>
</html>


You can download the full project from here.

https://github.com/raviyasas/keycloak-api-parent.git

I changed the default server port to 8090 in the application.properties file. Just go to the following links and check whether your application is working or not. 

http://localhost:8090/
http://localhost:8090/reservation

How to use the Keycloak server
  • Download the Keycloak server on https://www.keycloak.org/downloads.html 
  • Then download the Standalone server distribution zip file.


  • Unzip it to your machine.
  • Go to the bin folder. If you are on Windows OS just you can run the standalone.bat file or if you are using a Linux distribution, you may use standalone.sh file to start the server. 
  • Normally it will run on port 8080. But you can change it as you wish, go to standalone\configuration\standalone.xml and change the port.
  • Once you run the server, go to http://localhost:8080/auth/

You will be able to see it as follows.


This is to create an admin user. You can give any username and password you like. Once you create an admin user, you will be redirected to the following page. 


You can see the red square "Administration Console". Just click it and then you will be redirected to the following page which asks for your admin credentials for the admin you've already created.



Once you are logged inas , then you can see the below page.


Then you have to create a Realm. Just point your mouse to the left side and then you will be able to see a button like the below image.


Then you can create a realm by giving a realm name. 


Once you create a realm you will be able to see the following page.



Then you need to create a client for your application. Click on the Client on the left menu.


Then you can give any name for Client ID, I'm using it as "reservations". Once you have created a client, scroll down and then you will be able to see "Valid redirect URIs".


It is the entry point to your application after you logged in to it. You may use the port in which your Spring Boot application is running. My application is running on port 8090.

Then you have to add a new Role. Go to Roles in the menu and click on Add Role.




Once you click, you will be able to see this.


Add role name, I use it as "user". We need to use this role in our Spring Boot application. Once you save your role, Click again on Roles in the menu. Then go to Default Roles.


Then you need to add your role to Default Roles. Select your role and click Add selected.

Now you can create a new user. Click on Users in the menu.


Then click on Add users and give a username and click save. I used it as a "client".


Once you saved it, just go to the Credentials tab in your user and reset your password. Turn off the temporary tab for the password. 

Now everything is done on the Keycloak configuration side. Ready to go with the Spring Boot app.

Configure the Spring Boot application

It is actually a simple application. What you need to do is, add Keycloak dependencies to your pom.xml and add configurations to application.properties file. 

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>

 <groupId>com.app</groupId>
 <artifactId>api</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <packaging>jar</packaging>

 <name>api</name>
 <description>Demo project for Spring Boot</description>

 <parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>1.5.14.BUILD-SNAPSHOT</version>
  <relativePath/> <!-- lookup parent from repository -->
 </parent>

 <properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  <java.version>1.8</java.version>
  <keycloak.version>3.4.2.Final</keycloak.version>
 </properties>

 <dependencies>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-thymeleaf</artifactId>
  </dependency>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
   <groupId>org.keycloak</groupId>
   <artifactId>keycloak-spring-boot-starter</artifactId>
  </dependency>

  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-test</artifactId>
   <scope>test</scope>
  </dependency>
 </dependencies>

 <dependencyManagement>
  <dependencies>
   <dependency>
    <groupId>org.keycloak.bom</groupId>
    <artifactId>keycloak-adapter-bom</artifactId>
    <version>${keycloak.version}</version>
    <type>pom</type>
    <scope>import</scope>
   </dependency>
  </dependencies>
 </dependencyManagement>

 <build>
  <plugins>
   <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
   </plugin>
  </plugins>
 </build>

 <repositories>
  <repository>
   <id>spring-snapshots</id>
   <name>Spring Snapshots</name>
   <url>https://repo.spring.io/snapshot</url>
   <snapshots>
    <enabled>true</enabled>
   </snapshots>
  </repository>
  <repository>
   <id>spring-milestones</id>
   <name>Spring Milestones</name>
   <url>https://repo.spring.io/milestone</url>
   <snapshots>
    <enabled>false</enabled>
   </snapshots>
  </repository>
 </repositories>

 <pluginRepositories>
  <pluginRepository>
   <id>spring-snapshots</id>
   <name>Spring Snapshots</name>
   <url>https://repo.spring.io/snapshot</url>
   <snapshots>
    <enabled>true</enabled>
   </snapshots>
  </pluginRepository>
  <pluginRepository>
   <id>spring-milestones</id>
   <name>Spring Milestones</name>
   <url>https://repo.spring.io/milestone</url>
   <snapshots>
    <enabled>false</enabled>
   </snapshots>
  </pluginRepository>
 </pluginRepositories>


</project>


application.properties

#server port of Spring Boot application is running
server.port=8090

#specify the url that keycloak server is running
keycloak.auth-server-url=http://localhost:8080/auth

#realm name which you used when you configured keycloak
keycloak.realm=api
keycloak.public-client=true
#client name you created
keycloak.resource=reservations

#created user, when you configured keycloak
keycloak.security-constraints[0].auth-roles[0]=user
#url pattern needs to be secured
keycloak.security-constraints[0].security-collections[0].patterns[0]=/reservation/*


This is a simple example of Spring Boot and Keycloak integration. You will be able to see more details if you can go to Realm settings and then Login tab. Then you can very easily add functionalities for User registration, Remember me, Forgot password, Verify email...etc. You can download the full Spring Boot project from the below link.

https://github.com/raviyasas/SpringBoot-Keycloak-demo.git






Integrate Keycloak with Spring Boot Integrate Keycloak with Spring Boot Reviewed by Ravi Yasas on 11:06 AM Rating: 5

No comments:

Powered by Blogger.