Eine Kurzanleitung zur Verwendung von Keycloak mit Spring Boot

1. Übersicht

In diesem Artikel werden die Grundlagen zum Einrichten eines Keycloak-Servers, zum Verbinden einer Spring Boot-Anwendung und zur Verwendung mit Spring Security behandelt .

2. Was ist Schlüsselumhang?

Keycloak ist eine Open-Source-Lösung für das Identitäts- und Zugriffsmanagement, die auf moderne Anwendungen und Dienste ausgerichtet ist.

Keycloak bietet Funktionen wie Single Sign-On (SSO), Identity Brokering und Social Login, User Federation, Client-Adapter, eine Admin-Konsole und eine Account Management-Konsole. Um mehr über Keycloak zu erfahren, besuchen Sie bitte die offizielle Seite.

In unserem Tutorial verwenden wir die Admin-Konsole von Keycloak zum Einrichten und anschließende Herstellen einer Verbindung zu Spring Boot mithilfe des Keycloak-Clientadapters.

3. Einrichten eines Keycloak-Servers

3.1. Keycloak herunterladen und installieren

Es stehen mehrere Distributionen zur Auswahl.

In diesem Tutorial verwenden wir jedoch die eigenständige Version.

Laden Sie die eigenständige Server-Distribution Keycloak-11.0.2 von der offiziellen Quelle herunter.

Sobald wir die Standalone-Serverdistribution heruntergeladen haben, können wir Keycloak vom Terminal aus entpacken und starten:

unzip keycloak-11.0.2.zip cd keycloak-11.0.2/bin ./standalone.sh -Djboss.socket.binding.port-offset=100

Nach dem Ausführen von ./standalone.sh startet Keycloak seine Dienste. Sobald wir sehen, dass eine Zeile mit Keycloak 11.0.2 (WildFly Core 12.0.3.Final) gestartet wurde , wissen wir, dass der Start abgeschlossen ist.

Öffnen wir nun einen Browser und besuchen // localhost: 8180. Wir werden zu // localhost: 8180 / auth umgeleitet , um ein administratives Login zu erstellen:

Erstellen wir einen ersten Administrator mit dem Namen initial1 mit dem Kennwort zaq1! QAZ . Wenn Sie auf Erstellen klicken , wird eine Meldung angezeigt , die vom Benutzer erstellt wurde .

Wir können jetzt zur Administrationskonsole übergehen. Auf der Anmeldeseite geben wir die ersten Anmeldeinformationen des Administrators ein:

3.2. Ein Reich erschaffen

Eine erfolgreiche Anmeldung führt uns zur Konsole und öffnet den Standard- Master- Bereich für uns.

Hier konzentrieren wir uns auf die Erstellung eines benutzerdefinierten Bereichs.

Lassen Sie uns zur oberen linken oberen Ecke navigieren, um die Schaltfläche Realm hinzufügen zu entdecken :

Fügen Sie auf dem nächsten Bildschirm einen neuen Bereich mit dem Namen SpringBootKeycloak hinzu :

Nachdem Sie auf die Schaltfläche Erstellen geklickt haben , wird ein neuer Bereich erstellt und zu diesem weitergeleitet. Alle Operationen in den nächsten Abschnitten werden in diesem neuen SpringBootKeycloak- Bereich ausgeführt.

3.3. Client erstellen

Jetzt navigieren wir zur Seite Clients. Wie wir im Bild unten sehen können, enthält Keycloak Clients, die bereits integriert sind :

Wir müssen unserer Anwendung jedoch einen neuen Client hinzufügen, sodass wir auf Erstellen klicken . Wir rufen die neue Client- Login-App auf :

Im nächsten Bildschirm belassen wir für dieses Lernprogramm alle Standardeinstellungen mit Ausnahme des Felds Gültige Umleitungs-URIs . Dieses Feld sollte die Anwendungs-URL (s) enthalten, die diesen Client zur Authentifizierung verwenden :

Später erstellen wir eine Spring Boot-Anwendung, die am Port 8081 ausgeführt wird und diesen Client verwendet. Daher haben wir oben eine Weiterleitungs-URL von // localhost: 8081 / * verwendet.

3.4. Erstellen einer Rolle und eines Benutzers

Keycloak verwendet den rollenbasierten Zugriff. Daher muss jeder Benutzer eine Rolle haben.

Dazu müssen wir zur Seite Rollen navigieren :

Dann fügen wir die Benutzerrolle hinzu :

Jetzt haben wir eine Rolle, die Benutzern zugewiesen werden kann, aber es gibt noch keine Benutzer. Gehen wir also zur Benutzerseite und fügen eine hinzu:

Wir werden einen Benutzer namens user1 hinzufügen:

Sobald der Benutzer erstellt wurde, wird eine Seite mit ihren Details angezeigt:

Wir können jetzt zur Registerkarte Anmeldeinformationen gehen . Wir setzen das ursprüngliche Passwort auf [E-Mail geschützt] :

Schließlich navigieren wir zur Registerkarte Rollenzuordnungen . Wir werden die Benutzerrolle unserem Benutzer1 zuweisen :

4. Generieren von Zugriffstoken mit der Keycloak-API

Keycloak bietet eine REST-API zum Generieren und Aktualisieren von Zugriffstoken. Mit dieser API können wir ganz einfach unsere eigene Anmeldeseite erstellen.

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.

Wir haben auch gesehen, wie Sie Spring Security einrichten und in Verbindung mit Keycloak verwenden. Eine funktionierende Version des in diesem Artikel gezeigten Codes ist auf Github verfügbar.