SSO und Keycloak als IAM in Anwendungen


 Effizientes Identitäts- und Zugriffsmanagement mit Keycloak: Vereinfachen Sie die Authentifizierung in Ihren Anwendungen und steigern Sie die Sicherheit

 


 

 


Ein Single Sign-On (SSO)-Verfahren ermöglicht Benutzern, sich einmal bei einem Dienst anzumelden und dann auf mehrere Dienste zuzugreifen, ohne sich erneut anzumelden. Da Benutzer weniger Passwörter verwalten müssen und die Anmeldeinformationen zentralisiert und sicher gespeichert werden können, verbessert dies die Benutzerfreundlichkeit und die Sicherheit.

Keycloak ist eine Open-Source-Software für die Identitäts- und Zugriffsverwaltung (IAM). Es ermöglicht die Umsetzung von Single Sign-On (SSO) in Anwendungen und Diensten. Benutzer können mit Keycloak eine Vielzahl von Anwendungen und Diensten authentifizieren, ohne sich mehrmals anzumelden.
 


Es gibt eine Verbindung zwischen SSO und Keycloak darin, dass Keycloak als IAM-Lösung verwendet wird, um SSO in einer Anwendungslandschaft zu implementieren:
 
  • Die Einrichtung von Keycloak beginnt mit der Konfiguration und Einrichtung. Dies umfasst die Definition von Benutzern, Rollen, Gruppen und Anwendungen, die von SSO profitieren sollen.
  • Integration in Anwendungen: Die Anwendungen und Dienste, die SSO unterstützen sollen, werden so konfiguriert, dass Keycloak als Authentifizierungsdienst verwendet wird. Die Verwendung von Keycloak-Client-Adaptern oder -Bibliotheken kann dies ermöglichen.
  • Wenn ein Benutzer eine der SSO-fähigen Anwendungen nutzen möchte, wird er zur Keycloak-Anmeldeseite weitergeleitet. Der Benutzer gibt dort seine Anmeldedaten ein.
  • SSO-Token: Keycloak erstellt nach erfolgreicher Anmeldung ein SSO-Token, der alle Informationen über den Benutzer und seine Berechtigungen enthält. Die Anwendung erhält diesen Token zurück.
  • Zugriff auf Anwendungen: Die Anwendung verwendet das SSO-Token, das der Benutzer erhält, um seine Berechtigungen zu überprüfen. Der Benutzer kann nun die Anwendung nutzen, ohne sich erneut anzumelden.
  • Single Sign-Out: Da alle denselben SSO-Token-Server verwenden, wird der Benutzer, der sich von einer der SSO-fähigen Anwendungen abmeldet, auch von allen anderen abgemeldet.

    Die Verwendung von Keycloak bietet gleichzeitig Sicherheitsfunktionen wie die Möglichkeit zur Zwei-Faktor-Authentifizierung, die Verwaltung von Benutzerzugriffsrechten und andere Funktionen, die die Implementierung von SSO erheblich erleichtern. Es ist eine effektive Lösung für das Identitäts- und Zugriffsmanagement in einer Vielzahl von Situationen, insbesondere in komplexen Umgebungen.

    Hier ist ein einfaches Konfigurationsbeispiel für die Integration von Keycloak in eine Anwendung, um Single Sign-On (SSO) zu ermöglichen. Da Spring Boot und Spring Security mit Keycloak gut integriert sind, werde ich in diesem Beispiel eine Java-Anwendung verwenden, die mit der Spring Security-Bibliothek entwickelt wurde.



     

    Keycloak-Setup

    Installation und konfigurieration von Keycloak nach Bedarf -  Realm, Clients, Benutzer und Rollen sollen ordnungsgemäß eingerichtet.

     
    Quelle: thomasvitale.com

    Konfiguration der Spring Boot-Anwendung

    Erforderlichen Abhängigkeiten zu build.gradle (Gradle) oder pom.xml (Maven);  einschließlich Spring Boot, Spring Security und Keycloak.

     

    In Gradle:

    dependencies {
        implementation 'org.springframework.boot:spring-boot-starter-security'
        implementation 'org.keycloak:keycloak-spring-boot-starter'
        // Weitere Abhängigkeiten nach Bedarf
    }

     

    Spring Boot-Anwendung Konfiguration, um Keycloak zu verwenden. Eine Datei namens application.properties (oder application.yml) soll erstellt werden dort die Keycloak-Konfigurationsdetails hinzufügen.

    spring.security.oauth2.client.registration.keycloak.client-id=my-app
    spring.security.oauth2.client.registration.keycloak.client-secret=my-secret
    spring.security.oauth2.client.registration.keycloak.authorization-grant-type=authorization_code
    spring.security.oauth2.client.registration.keycloak.redirect-uri-template=http://localhost:8080/login/oauth2/code/keycloak
    spring.security.oauth2.client.provider.keycloak.token-uri=${keycloak.auth-server-url}/realms/my-realm/protocol/openid-connect/token
    spring.security.oauth2.client.provider.keycloak.user-info-uri=${keycloak.auth-server-url}/realms/my-realm/protocol/openid-connect/userinfo
    spring.security.oauth2.client.provider.keycloak.jwk-set-uri=${keycloak.auth-server-url}/realms/my-realm/protocol/openid-connect/certs
    spring.security.oauth2.client.registration.keycloak.scope=openid,profile,email
    spring.security.oauth2.client.registration.keycloak.client-name=my-app

     

    Sicherheitseinstellungen festlegen

    Spring Security sollte so konfiguriert werden, dass Keycloak als Authentifizierungsanbieter verwendet wird. Dazu sollte die folgende Konfigurationsklasse erstellt werden. Diese kann je nach Bedarf natürlich erweitert werden.

     

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
    import org.springframework.security.oauth2.client.oidc.authentication.OidcIdTokenDecoderFactory;
    import org.springframework.security.oauth2.client.oidc.authentication.OidcUserService;
    import org.springframework.security.oauth2.client.registration.ClientRegistration;
    import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
    import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;
    import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames;

    @Configuration
    public class SecurityConfig {

        @Bean
        public ClientRegistrationRepository clientRegistrationRepository() {
            ClientRegistration registration = ClientRegistration.withRegistrationId("keycloak")
                    .clientId("my-app")
                    .clientSecret("my-secret")
                    .authorizationGrantType("authorization_code")
                    .redirectUriTemplate("{baseUrl}/login/oauth2/code/{registrationId}")
                    .scope("openid", "profile", "email")
                    .authorizationUri("http://localhost:8080/auth/realms/my-realm/protocol/openid-connect/auth")
                    .tokenUri("http://localhost:8080/auth/realms/my-realm/protocol/openid-connect/token")
                    .userInfoUri("http://localhost:8080/auth/realms/my-realm/protocol/openid-connect/userinfo")
                    .jwkSetUri("http://localhost:8080/auth/realms/my-realm/protocol/openid-connect/certs")
                    .clientName("my-app")
                    .build();

            return new InMemoryClientRegistrationRepository(registration);
        }

        @Bean
        public OidcUserService oidcUserService() {
            OidcUserService oidcUserService = new OidcUserService();
            oidcUserService.setIdTokenClaimNames(IdTokenClaimNames.SUB, IdTokenClaimNames.PREFERRED_USERNAME);

            return oidcUserService;
        }

        @Bean
        public SimpleAuthorityMapper authorityMapper() {
            return new SimpleAuthorityMapper();
        }

        @Configuration
        public class OAuth2LoginConfig extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {

            @Override
            public void configure(HttpSecurity http) throws Exception {
                http
                    .authorizeRequests(authorizeRequests ->
                        authorizeRequests
                            .antMatchers("/", "/index.html").permitAll()
                            .anyRequest().authenticated()
                    )
                    .oauth2Login()
                        .userInfoEndpoint()
                            .oidcUserService(oidcUserService())
                            .and()
                        .loginPage("/login")
                            .failureUrl("/login-error")
                            .permit

     


 

Keycloak bietet eine grafische Benutzeroberfläche (GUI) über das Admin Console

Mit der Benutzer und Gruppen könnten verwaltet werden.

Die grundlegenden Schritte in der Keycloak-GUI:

Gruppen erstellen:

  1. Anmeldung bei Keycloak:

    • Melden Sie sich bei Ihrer Keycloak-Instanz an.
  2. Zugriff auf das Admin Console:

    • Gehen Sie zum "Admin Console" von Keycloak.
  3. Realm auswählen:

    • Wählen Sie den gewünschten Realm aus, in dem Sie Gruppen erstellen möchten.
  4. Gruppen erstellen:

    • Navigieren Sie zu "Groups" in der linken Navigationsleiste.
    • Klicken Sie auf "New" oder "Add Group", um eine neue Gruppe hinzuzufügen.
    • Geben Sie einen Namen für die Gruppe ein und klicken Sie auf "Save".

Benutzer erstellen:

  1. Benutzer hinzufügen:

    • Navigieren Sie zu "Users" in der linken Navigationsleiste.
    • Klicken Sie auf "Add User", um einen neuen Benutzer zu erstellen.
  2. Benutzerinformationen eingeben:

    • Geben Sie die erforderlichen Benutzerinformationen ein.
    • Klicken Sie auf "Save" oder "Add User" am Ende der Seite.

Benutzer zu Gruppen hinzufügen:

  1. Benutzer bearbeiten:

    • Wählen Sie den erstellten Benutzer aus der Liste aus.
    • Navigieren Sie zum Tab "Groups".
  2. Gruppenzuweisung:

    • Wählen Sie die Gruppen aus, zu denen der Benutzer gehören soll.
    • Klicken Sie auf "Join" oder eine ähnliche Schaltfläche.

Single Sign-On-Konfiguration:

  1. Client konfigurieren:

    • Navigieren Sie zum "Clients"-Bereich im Admin Console.
    • Wählen Sie den Client aus, für den Sie SSO konfigurieren möchten.
  2. SSO konfigurieren:

    • Stellen Sie sicher, dass die Einstellung "Single Sign On" für den Client aktiviert ist.
    • Konfigurieren Sie ggf. andere relevante Einstellungen, wie "Login Theme" und "Logout Redirect URI".
  3. Testen:

    • Testen Sie die SSO-Funktion, indem Sie sich bei einem Client anmelden und dann zu einem anderen wechseln, um zu sehen, ob Sie automatisch angemeldet werden.

Die Keycloak-GUI ermöglicht eine benutzerfreundliche Verwaltung von Benutzern, Gruppen und anderen Einstellungen für die Authentifizierung und das Single Sign-On.

 

 

Keycloak mit einer Spring-Boot-Anwendung in Java zu konfigurieren

 

Einige Schritte im Quellcode der Anwendung müssen durchführt werden.

Die grundlegende Schritte für die Integration von Keycloak in einer Spring-Boot-Anwendung:

 

Schritt 1: Keycloak-Abhängigkeiten hinzufügen

Fügen Sie die erforderlichen Keycloak-Abhängigkeiten zu Ihrer pom.xml-Datei hinzu:

xml
<dependency> <groupId>org.keycloak</groupId> <artifactId>keycloak-spring-boot-starter</artifactId> <version>insert_version_here</version> <!-- Ersetzen Sie "insert_version_here" durch die gewünschte Version --> </dependency>

Schritt 2: Anwendungsproperties konfigurieren

Fügen Sie die Keycloak-Konfiguration zu Ihrer application.properties- oder application.yml-Datei hinzu:

properties
# Keycloak Konfiguration keycloak.auth-server-url=http://keycloak-server:port/auth keycloak.realm=your-realm keycloak.resource=your-client-id keycloak.public-client=true

Schritt 3: Keycloak-Konfiguration in Spring Security aktivieren

Erstellen Sie eine Konfigurationsklasse, um die Keycloak-Integration in Spring Security zu aktivieren:

java
import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class KeycloakConfig { @Bean public KeycloakSpringBootConfigResolver keycloakConfigResolver() { return new KeycloakSpringBootConfigResolver(); } }

Schritt 4: Sicherheitskonfiguration anpassen

Erstellen Sie eine Klasse, die KeycloakWebSecurityConfigurerAdapter erweitert, um die Sicherheitskonfiguration anzupassen:

java
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.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @Configuration public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter { @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) { KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider(); auth.authenticationProvider(keycloakAuthenticationProvider); } @Bean public KeycloakAuthenticationProvider keycloakAuthenticationProvider() { return keycloakAuthenticationProvider(); } @Override protected void configure(HttpSecurity http) throws Exception { super.configure(http); http.authorizeRequests() .antMatchers("/public/**").permitAll() // Öffentliche Pfade .antMatchers("/secured/**").authenticated(); // Gesicherte Pfade, erfordern Authentifizierung } }

Schritt 5: KeycloakSecurityContext in Ihren Controllern nutzen

In Ihren Controllern können Sie KeycloakSecurityContext verwenden, um auf Benutzerinformationen zuzugreifen:

java
import org.keycloak.KeycloakPrincipal; import org.keycloak.KeycloakSecurityContext; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; @RestController public class MyController { @GetMapping("/secured/resource") public String getSecuredResource(HttpServletRequest request) { KeycloakPrincipal<KeycloakSecurityContext> principal = (KeycloakPrincipal<KeycloakSecurityContext>) request.getUserPrincipal(); String username = principal.getKeycloakSecurityContext().getIdToken().getPreferredUsername(); return "Hello, " + username + "! This is a secured resource."; } }

Wichtig. Dies ist nur eine grundlegende Konfiguration.