1. Información general
En este artículo, cubriremos los conceptos básicos de la configuración de un servidor Keycloak, cómo conectarle una aplicación Spring Boot y cómo usarlo con Spring Security .
2. ¿Qué es Keycloak?
Keycloak es una solución de gestión de acceso e identidad de código abierto dirigida a aplicaciones y servicios modernos.
Keycloak ofrece funciones como inicio de sesión único (SSO), intermediación de identidades e inicio de sesión social, federación de usuarios, adaptadores de clientes, una consola de administración y una consola de gestión de cuentas. Para obtener más información sobre Keycloak, visite la página oficial.
En nuestro tutorial, usaremos la Consola de administración de Keycloak para configurar y luego conectarnos a Spring Boot usando el Adaptador de cliente de Keycloak.
3. Configuración de un servidor Keycloak
3.1. Descarga e instalación de Keycloak
Hay varias distribuciones para elegir.
Sin embargo, en este tutorial, usaremos la versión independiente.
Descarguemos la distribución del servidor independiente Keycloak-11.0.2 de la fuente oficial.
Una vez que hayamos descargado la distribución del servidor independiente, podemos descomprimir e iniciar Keycloak desde la terminal:
unzip keycloak-11.0.2.zip cd keycloak-11.0.2/bin ./standalone.sh -Djboss.socket.binding.port-offset=100
Después de ejecutar ./standalone.sh , Keycloak iniciará sus servicios. Una vez que veamos una línea que contiene Keycloak 11.0.2 (WildFly Core 12.0.3.Final) iniciada , sabremos que su inicio se completó.
Ahora abramos un navegador y visite // localhost: 8180. Seremos redirigidos a // localhost: 8180 / auth para crear un inicio de sesión administrativo:

Creemos un usuario administrador inicial llamado initial1 con la contraseña zaq1! QAZ . Al hacer clic en Crear , veremos un mensaje creado por el usuario .
Ahora podemos pasar a la Consola administrativa. En la página de inicio de sesión, ingresaremos las credenciales del usuario administrador inicial:

3.2. Creando un reino
Un inicio de sesión exitoso nos llevará a la consola y nos abrirá el reino maestro predeterminado .
Aquí nos centraremos en crear un reino personalizado.
Naveguemos hasta la esquina superior izquierda para descubrir el botón Agregar reino :

En la siguiente pantalla, agreguemos un nuevo reino llamado SpringBootKeycloak :

Después de hacer clic en el botón Crear , se creará un nuevo reino y seremos redirigidos a él. Todas las operaciones en las siguientes secciones se realizarán en este nuevo reino SpringBootKeycloak .
3.3. Crear un cliente
Ahora navegaremos a la página Clientes. Como podemos ver en la imagen a continuación, Keycloak viene con Clientes que ya están integrados :

Pero necesitamos agregar un nuevo cliente a nuestra aplicación, entonces haremos clic en Crear . Llamaremos a la nueva aplicación de inicio de sesión del cliente :

En la siguiente pantalla, para este tutorial, dejaremos todos los valores predeterminados excepto el campo URI de redireccionamiento válido . Este campo debe contener las URL de la aplicación que utilizarán este cliente para la autenticación :

Más adelante, crearemos una aplicación Spring Boot ejecutándose en el puerto 8081 que usará este cliente. Por lo tanto, hemos utilizado una URL de redireccionamiento de // localhost: 8081 / * anterior.
3.4. Creación de un rol y un usuario
Keycloak utiliza el acceso basado en roles. Por tanto, cada usuario debe tener un rol.
Para hacer eso, necesitamos navegar a la página Roles :

Luego, agregaremos el rol de usuario :

Ahora tenemos un rol que se puede asignar a los usuarios, pero todavía no hay usuarios. Así que vayamos a la página Usuarios y agreguemos uno:

Agregaremos un usuario llamado user1:

Una vez creado el usuario, se mostrará una página con sus detalles:

Ahora podemos ir a la pestaña Credenciales . Configuraremos la contraseña inicial en [correo electrónico protegido] :

Finalmente, navegaremos a la pestaña Asignaciones de roles . Asignaremos el rol de usuario a nuestro usuario1 :

4. Generación de tokens de acceso con la API de Keycloak
Keycloak proporciona una API REST para generar y actualizar tokens de acceso. Podemos usar fácilmente esta API para crear nuestra propia página de inicio de sesión.
First, we need to acquire an access token from Keycloak by sending a POST request to this URL:
//localhost:8180/auth/realms/master/protocol/openid-connect/token
The request should have this JSON body:
{ 'client_id': 'your_client_id', 'username': 'your_username', 'password': 'your_password', 'grant_type': 'password' }
In response, we'll get an access_token and a refresh_token.
The access token should be used in every request to a Keycloak-protected resource by simply placing it in the Authorization header:
headers: { 'Authorization': 'Bearer' + access_token }
Once the access token has expired, we can refresh it by sending a POST request to the same URL as above, but containing the refresh token instead of username and password:
{ 'client_id': 'your_client_id', 'refresh_token': refresh_token_from_previous_request, 'grant_type': 'refresh_token' }
Keycloak will respond to this with a new access_token and refresh_token.
5. Creating a Spring Boot Application
5.1. Dependencies
The latest Spring Boot Keycloak Starter dependencies can be found on Maven Central.
The Keycloak Spring Boot adaptercapitalizes on Spring Boot’s auto-configuration, so all we need to do is add the Keycloak Spring Boot starter to our project.
Within the dependencies XML element, we need the following to run Keycloak with Spring Boot:
org.keycloak keycloak-spring-boot-starter
After the dependencies XML element, we need to specify dependencyManagement for Keycloak:
org.keycloak.bom keycloak-adapter-bom 11.0.2 pom import
The following embedded containers are supported now and don't require any extra dependencies if using Spring Boot Keycloak Starter:
- Tomcat
- Undertow
- Jetty
5.2. Thymeleaf Web Pages
We're using Thymeleaf for our web pages.
We've got three pages:
- external.html – an externally facing web page for the public
- customers.html – an internally facing page that will have its access restricted to only authenticated users with the role user.
- layout.html – a simple layout, consisting of two fragments, that is used for both the externally facing page and the internally facing page
The code for the Thymeleaf templates is available on Github.
5.3. Controller
The web controller maps the internal and external URLs to the appropriate Thymeleaf templates:
@GetMapping(path = "/") public String index() { return "external"; } @GetMapping(path = "/customers") public String customers(Principal principal, Model model) { addCustomers(); model.addAttribute("customers", customerDAO.findAll()); model.addAttribute("username", principal.getName()); return "customers"; }
For the path /customers, we're retrieving all customers from a repository and adding the result as an attribute to the Model. Later on, we iterate through the results in Thymeleaf.
To be able to display a username, we're injecting the Principal as well.
Note that we're using customer here just as raw data to display, and nothing more.
5.4. Keycloak Configuration
Here's the basic, mandatory configuration:
keycloak.auth-server-url=//localhost:8180/auth keycloak.realm=SpringBootKeycloak keycloak.resource=login-app keycloak.public-client=true
As we recall, we started Keycloak on port 8180, hence the path specified in keycloak.auth-server-url. We enter the realm name we created in the Keycloak admin console.
The value we specify in keycloak.resource matches the client we named in the admin console.
Here are the security constraints we'll be using:
keycloak.security-constraints[0].authRoles[0]=user keycloak.security-constraints[0].securityCollections[0].patterns[0]=/customers/*
These constraints ensure that every request to /customers/* will only be authorized if the one requesting it is an authenticated user with the role user.
Additionally, we can define keycloak.principal-attribute as preferred_username so as to populate our controller's Principal with a proper user:
keycloak.principal-attribute=preferred_username
5.5. Demonstration
Now, we're ready to test our application. To run a Spring Boot application, we can start it easily through an IDE like Spring Tool Suite (STS) or run this command in the terminal:
mvn clean spring-boot:run
On visiting //localhost:8081 we see:

Now we click customers to enter the intranet, which is the location of sensitive information.
We can see that we've been redirected to authenticate through Keycloak to see if we're authorized to view this content:

Once we log in as user1, Keycloak will verify our authorization – that we have the user role – and we'll be redirected to the restricted customers page:

Now we've finished the set up of connecting Spring Boot with Keycloak and demonstrating how it works.
As we can see, the entire process of calling the Keycloak Authorization Server was handled seamlessly by Spring Boot for us. We did not have to call the Keycloak API to generate the Access Token ourselves, or even send the Authorization header explicitly in our request for protected resources.
Next, we'll be reviewing how to use Spring Security in conjunction with our existing application.
6. Spring Security
There is a Keycloak Spring Security Adapter, and it’s already included in our Spring Boot Keycloak Starter dependency. We'll now see how to integrate Spring Security with Keycloak.
6.1. Dependency
To use Spring Security with Spring Boot, we must add this dependency:
org.springframework.boot spring-boot-starter-security 2.2.6.RELEASE
The latest Spring Boot Starter Security release can be found on Maven Central.
6.2. Configuration Class
Keycloak provides a KeycloakWebSecurityConfigurerAdapter as a convenient base class for creating a WebSecurityConfigurer instance.
This is helpful because any application secured by Spring Security requires a configuration class that extends WebSecurityConfigurerAdapter:
@Configuration @EnableWebSecurity @ComponentScan(basePackageClasses = KeycloakSecurityComponents.class) class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter { @Autowired public void configureGlobal( AuthenticationManagerBuilder auth) throws Exception { KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider(); keycloakAuthenticationProvider.setGrantedAuthoritiesMapper( new SimpleAuthorityMapper()); auth.authenticationProvider(keycloakAuthenticationProvider); } @Bean public KeycloakSpringBootConfigResolver KeycloakConfigResolver() { return new KeycloakSpringBootConfigResolver(); } @Bean @Override protected SessionAuthenticationStrategy sessionAuthenticationStrategy() { return new RegisterSessionAuthenticationStrategy( new SessionRegistryImpl()); } @Override protected void configure(HttpSecurity http) throws Exception { super.configure(http); http.authorizeRequests() .antMatchers("/customers*") .hasRole("user") .anyRequest() .permitAll(); } }
In the code above, the method configureGlobal() tasks the SimpleAuthorityMapper to make sure roles are not prefixed with ROLE_.
Another method, keycloakConfigResolver defines that we want to use the Spring Boot properties file support instead of the default keycloak.json.
Because we've set up the security constraints with Spring Security, we can remove or comment these security constraints we'd placed earlier in the properties file:
#keycloak.security-constraints[0].authRoles[0]=user #keycloak.security-constraints[0].securityCollections[0].patterns[0]=/customers/*
Now, after we authenticate, we'll be able to access the internal customers' page, same as we saw before.
7. Conclusion
In this tutorial, we’ve configured a Keycloak server and used it with a Spring Boot Application.
También hemos visto cómo configurar Spring Security y usarlo junto con Keycloak. Una versión funcional del código que se muestra en este artículo está disponible en Github.