Securing Spring Boot application with Keycloak

This tutorial covers securing a Spring Boot applications with Keycloak. Keycloak is an open source identity and access management solution which aims at securing applications and services. Users can authenticate with Keycloak rather coding individual applications. So, the applications don’t have to deal with login authentication forms, and other security concerns in the application code. Let’s see how you can add Keycloak security to a Spring Boot application.

Setting up Keycloak

There are several options to get started with Keycloak. You can just download the latest release from https://www.keycloak.org/downloads

Other than that, you can simply start Keycloak as Docker container image:

docker run --rm     --name keycloak    -e KEYCLOAK_USER=admin    -e KEYCLOAK_PASSWORD=admin \     -p 8180:8180    -it quay.io/keycloak/keycloak    -b 0.0.0.0    -Djboss.http.port=8180     

Check from the logs that the server started:

13:17:59,268 INFO  [org.jboss.as.server] (ServerService Thread Pool -- 46) WFLYSRV0010: Deployed "keycloak-server.war" (runtime-name : "keycloak-server.war") 13:17:59,317 INFO  [org.jboss.as.server] (Controller Boot Thread) WFLYSRV0212: Resuming server 13:17:59,319 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: Keycloak 12.0.2 (WildFly Core 13.0.3.Final) started in 17105ms - Started 687 of 972 services (687 services are lazy, passive or on-demand) 13:17:59,321 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0060: Http management interface listening on http://127.0.0.1:9990/management 13:17:59,321 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0051: Admin console listening on http://127.0.0.1:9990 

Now we will create a Keycloak Realm with a Client authentication policy. You can access the administration console of Keycloak (http://localhost:8180 in our example) or you can just use the following script.sh:

#!/bin/bash  cd /opt/jboss/keycloak/bin   ./kcadm.sh config credentials --server http://localhost:8180/auth --realm master --user admin --password admin  ./kcadm.sh create realms -s realm=spring-realm -s enabled=true -o  ./kcadm.sh create users -r spring-realm -s username=demo -s enabled=true  ./kcadm.sh set-password -r spring-realm --username demo --new-password demo  ./kcadm.sh create clients -r spring-realm -s clientId=simple-webapp -s publicClient="true"  -s "redirectUris=[\"http://localhost:8080/*\"]" -s enabled=true  ./kcadm.sh create roles -r spring-realm -s name=Users  ./kcadm.sh add-roles --uusername demo --rolename Users -r spring-realm 

This script invokes the Keycloak CLI (kcadm.sh) to perform all the required steps to create the “spring-realm”. To execute it, you can attach to the Docker process and upload and execute it as follows:

docker cp script.sh keycloak:/opt/jboss/keycloak/bin docker exec -it keycloak chmod 755 /opt/jboss/keycloak/bin/script.sh docker exec -it keycloak /opt/jboss/keycloak/bin/script.sh 

You should see from the script log that the execution completed successfully:

  . . . . Created new user with id '75e22b77-fd58-4744-b07e-3687aa8d9fc9' Created new client with id '506ff918-5135-492d-8ee0-9a26211090fe' Created new role with id 'Users' 

Setting up the Spring Boot application

Now let’s set up a minimal Spring Boot application which has a Controller secured against the Keycloak Realm. Here is our basic Controller:

@Controller
class CustomerController {
  @GetMapping(path = "/customers")
  public String getCustomers(Model model) {
    model.addAttribute("customers", Arrays.asList("John Smith", "Uncle Tom", "Fred Flintstone"));
    return "customers";
  }

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

The most interesting part is the application.properties file which contains the Keycloak settings, which are based on the Realm URL we have just created:

keycloak.auth-server-url=http://localhost:8180/auth keycloak.realm=spring-realm keycloak.resource=simple-webapp keycloak.public-client=true keycloak.security-constraints[0].authRoles[0]=Users keycloak.security-constraints[0].securityCollections[0].patterns[0]=/customers/* 

In order to build and deploy the application, we need to add the standard web and test starters plus keycloak-spring-boot-starter:

<?xml version="1.0" encoding="UTF-8"?><project>
   	
   <dependencies>
       		
      <dependency>
          			
         <groupId>org.springframework.boot</groupId>
          			
         <artifactId>spring-boot-starter-freemarker</artifactId>
          		
      </dependency>
       		
      <dependency>
          			
         <groupId>org.keycloak</groupId>
          			
         <artifactId>keycloak-spring-boot-starter</artifactId>
          		
      </dependency>
       		
      <dependency>
          			
         <groupId>org.springframework.boot</groupId>
          			
         <artifactId>spring-boot-starter-web</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>
    
</project>

Run the application with:

$ mvn install spring-boot:run 

Now try to access the /customers URL: http://localhost:8080/customers .The Login page from Keycloak will display:

 keycloak spring boot tutorial spring boot keycloak

If you enter the credentials “demo/demo”, you will have access to the main application page:

 keycloak spring boot tutorial spring boot keycloak

That’s all! We just had a quickstart tour on how to secure a Spring Boot application with Keycloak

Source code for this tutorial: https://github.com/fmarchioni/masterspringboot/tree/master/security/keycloak-demo