Secure Spring Boot Full Stack Website with Keycloak

In this tutorial, we will build a sample Spring Boot full stack web application and secure the web pages using Keycloak.

Keycloak is an open source Identity and Access Management tool that uses standard protocols such as OAuth 2.0, OpenID Connect, and SAML to secure web applications and web services.

Follow the steps below to complete this example:

Set Up Keycloak

The first step is to download, setup, and run the Keycloak Server. If you have already set up the Keycloak server then continue from step two. Otherwise, go to our Keycloak quickstart tutorial to set up the Keycloak Server for using it with this example.

Create a Spring Boot Full stack Web Application

  1. To generate the initial project structure, go to Spring Initializr at https://start.spring.io and create a Spring Boot application with details as follows:
    • Project: Choose Gradle Project or Maven Project.
    • Language: Java
    • Spring Boot: Latest stable version of Spring Boot is selected by default. So leave it as is.
    • Project Metadata: Provide group name in the Group field. The group name is the id of the project. In Artifact field, provide the name of your project. In the package field, provide package name for your project. Next, select your preferred version of Java that is installed on your computer and is available on your local environment.
    • Dependencies: Add dependencies for Spring Web, Spring Boot DevTools, and Spring Security.

    Refer to the image below for example:

  2. Click the GENERATE button and save/download the project zip bundle.
  3. Extract the project to your preferred working directory.
  4. Import the project to your preferred Java development IDE such as Eclipse or IntelliJ IDEA.

The final project structure of our sample application will look something like this after completion in a hierarchical package presentation view:

Add Keycloak Spring Dependencies

To secure a Spring Boot web application, you must add Keycloak Spring Boot adapter Jar to your application. The Keycloak Spring Boot adapter takes benefit of Spring Boot's autoconfiguration, so all you need to do, is add the Keycloak Spring Boot Starter to your Spring Boot project.

For Gradle

Add the following dependency to build.gradle file:

keycloak-sample/build.gradle

implementation group: 'org.keycloak', name: 'keycloak-spring-boot-starter', version: '20.0.1'

For Maven

Add the following dependency to the pom.xml file:

keycloak-sample/pom.xml



You can the latest version of keycloak-spring-boot-starter in the Maven Repository .

Add Application Configurations

Add the following configuration to the application.properties file. Replace the values of server.port, keycloak.realm, keycloak.resource with values that is relevant to your project:

mywebsite-keycloak-sample/src/main/resources/application.properties

#port on which the application would run
server.port = 8081
keycloak.realm = tutorialsbuddy-realm
keycloak.auth-server-url = http://127.0.0.1:8080/auth
keycloak.ssl-required = external
#keycloak resource is the client ID
keycloak.resource = tutorialsbuddy-client
keycloak.use-resource-role-mappings = true
keycloak.public-client = true

Create SecurityConfig Java Class

This SecurityConfig class file must extends KeycloakWebSecurityConfigurerAdapter abstract class. KeycloakWebSecurityConfigurerAdapter is a convenient base class provided by Keycloak for creating a WebSecurityConfigurer instance.

The SecurityConfig class must be annotated with the following annotations:

  • @Configuration - This annotation indicates that the class is a configuration class containing bean definitions for the application context.
  • @EnableWebSecurity - This annotation indicates that the class is a Spring Security configuration with information telling how to authenticate users. It provides security configuration via HttpSecurity which is provided as a method parameter in a method called configure and allows you to configure accessibility based on the url-patterns, handlers and authentication endpoints.
  • @EnableGlobalMethodSecurity(prePostEnabled = true) - This annotation enables Spring Security global method security. The use of prePostEnabled = true enables @PreAuthorize and @PostAuthorize annotations.
  • @ComponentScan(basePackageClasses = KeycloakSecurityComponents.class) - The @ComponentScan tells Spring to scan the packages assigned to basePackageClasses .
mywebsite-keycloak-sample/src/main/java/com/mywebsite/sample/keycloak/config/KeycloakConfig.java

package com.mywebsite.sample.keycloak.config;

import org.keycloak.adapters.springsecurity.KeycloakSecurityComponents;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
public class KeycloakConfig extends KeycloakWebSecurityConfigurerAdapter {


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http.authorizeRequests().antMatchers("/index").permitAll().anyRequest().authenticated();
    }


    @Override
    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
        return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
    }


    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        KeycloakAuthenticationProvider keycloakAuthenticationProvider =
                keycloakAuthenticationProvider();
        keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());

        auth.authenticationProvider(keycloakAuthenticationProvider);
    }

}

Create a Controller Class

Create a PageController.java Java class with two methods to route requests to html pages:

mywebsite-keycloak-sample/src/main/java/com/mywebsite/sample/keycloak/controller/PageController.java

package com.mywebsite.sample.keycloak.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class PageController {

    @GetMapping(value = "/index")
    String index(Model model) {
        return "index";
    }

    @GetMapping(value = "/dashboard")
    String dashboard(Model model) {
        return "view-names";
    }

}

Create keycloakConfigResolver Reference Method

Create a keycloakConfigResolver reference method in the Spring Boot main application class. This method must be annotated with @Bean annotation and also must return an instance of KeycloakSpringBootConfigResolver class. The use of this keycloakConfigResolver reference will make the application to use Spring Boot configuration properties file instead of the Keycloak default keycloak.json file.

mywebsite-keycloak-sample/src/main/java/com/mywebsite/sample/keycloak/MywebsiteKeycloakSampleApplication.java

package com.mywebsite.sample.keycloak;

import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class MywebsiteKeycloakSampleApplication {

    public static void main(String[] args) {
        SpringApplication.run(MywebsiteKeycloakSampleApplication.class, args);
    }

    @Bean
    public KeycloakSpringBootConfigResolver keycloakConfigResolver() {
        return new KeycloakSpringBootConfigResolver();
    }
}

Create Two HTML Pages

Go to src/main/resoures/templates project folder and create two HTML files as follows:

  1. index.html
  2. 
        
    

  3. dashboard.html
  4. 
        
    

Run and Test the Application

  1. Run your Spring Boot application.
  2. Launch your browser and go to http://localhost:8081. You will see the index page as shown in the example below:
  3. If you click the View Names link, you will be taken to the Keycloak's login page because the second dashboard.html page is secured by Keycloak and is not accessible. To view the dashboard.html page, create a new user account from register link on the Keycloak login page (user registration feature must be enabled for your realm from the Login settings page of your admin console). If you login successfully, you will see the dashboard page.

Summary

Configurations! you have learned how to integrate Keycloak with a Spring Boot full stack website.