# SSO / OAuth / OpenID Connect Benutzerverwaltung mittels SSO, OAuth und OpenID Connect. # [internal] Keycloak als IDP für SQUEEZE

Die OAuth-Integration von Squeeze befindet sich in einer frühen Entwicklungsphase. Das System ist stabil und wird erfolgreich bei sowohl internen als auch produktiven Systemen eingesetzt. Allerdings ist geplant, die Integration kontinuierlich zu verbessern und ggf. anzupassen, insbesondere um die Software näher an Cloud-Standards heranzuführen. Daher ist bei der Verwendung von Keycloak (sowohl ohne als auch mit SSO) damit zu rechnen, dass das System periodisch Änderungen erfährt, die manuelle Updateaufwände erzeugt. Fragen zum Status dieser Entwicklung bitte an richten.

## Konzept - **Ein SQUEEZE Mandant wird über einen Keycloak-Realm abgesichert.** - Keycloak kann als Identity Broker für andere Identity Provider (Okta, Auth0, Azure, usw.) agieren. - Keycloak kann eigene Benutzer verwalten. - User loggen sich via Keycloak ein. - Die UI nutzt die SQUEEZE API unter Verwendung des notwendigen Access Tokens. ### User-Synchronisierung

Im Folgenden gelten folgende zwei Begriffe: - **SQUEEZE User**: Ein Benutzer, der durch SQUEEZE verwaltet und in der Datenbank des Mandanten gespeichert wird. - **Token User**: Der Benutzer, für den ein Access Token ausgestellt wurde. Dieser kommt i. d. R. von Keycloak bzw. einem hinterlegtem Identity Provider.

Bei jedem Request prüft die SQUEEZE API den genutzten Token auf Validität. Ist ein Token valide, wird ermittelt, ob zu dem Token User einen SQUEEZE User gefunden wird (**Matching**). Dieses System führt dazu, dass ein Mapping von Token User auf SQUEEZE User notwendig ist (**Mapping**). Wie dies funktioniert wird im folgenden erläutert.

**Merke:** SQUEEZE synchronisiert jeden Token User mit einem SQUEEZE User.

#### Matching Ein Token-User wird über folgende Properties mit einem SQUEEZE User gematcht. Beim ersten Match wird der Token User mit dem SQUEEZE User assoziiert.
**Token-Eigenschaft (Claim bzw. Header)****SQUEEZE User Eigenschaft**
subjectNetzwerk-ID (ggf. in UI nicht sichtbar)
emailE-Mail
emailLogin
#### Mapping Folgende Eigenschaften eines Token Users werden auf SQUEEZE User übertragen. **Einige Eigenschaften werden nur bei Neuanlage eines Users gesetzt**, aber nicht aktualisiert, falls sich diese Eigenschaften bei einem Token User ändern.
**Token-Eigenschaft (Claim bzw. Header)****SQUEEZE User Eigenschaft****Bei Neuanlage** **Bei Update**
- *Dieser Wert ist immer "oauth2"*NetzwerkXX
subjectNetzwerk-ID (ggf. in UI nicht sichtbar)X
emailE-MailX
emailLoginX
given\_nameVornameXX
family\_nameNachnameXX
### Rollen-Synchronisierung

Rollen werden aktuell exklusiv durch SQUEEZE verwaltet. Die Rollen eines Users werden also nicht auf Basis des Access Tokens ermittelt.

Bei Neuanlage eines Users werden konfigurierte Standard-Rollen an diesen User übergeben. Die Folgende Konfiguration sorgt bspw. dafür, dass neue User den Rollen mit den IDs 1 und 2 zugeordnet werden. Diese Zuordnung findet einmalig statt, ein Ändern dieser Konfiguration beeinflusst also bestehende User nicht. ```JSON "auth": { "oauth2": { "defaultRoleIds": "1,2" } } ``` ## Konfiguration Im Folgenden ist dokumentiert, wie die Integration mit Keycloak eingerichtet werden kann. ### Keycloak - Keycloak-Server bestimmen, der genutzt werden soll. - ,wenn noch kein Nutzer angelegt bei Fabian Terstegen anfragen. URL lautet aktuell : - https://**{keycloak.server}**/admin/console - Realm auswählen, der für die Authentifizierung des SQUEEZE Mandanten genutzt werden soll. - OpenID Connect Client anlegen - Dazu am besten das folgende Template verwenden. - In dem neuen Client müssen diese URLs auf die URL des Mandanten angepasst werden: - Redirect URIs - Web Origins - Base URL - ,wenn ein realm für 2 tenant genutzt werden sollen einfach ein neuen dexp-frontend-2 client anlegen. - *Optional: Für Tests bietet es sich an einen Testuser in Keycloak zu hinterlegen.* - Hier kann man sich dann einloggen https://**{keycloak.server}**/realms/**{deinNeuerRealm}**/account ```JSON { "clientId": "dexp-frontend", "name": "DEXPRO", "description": "", "baseUrl": "https://mandant.squeeze.one/ui", "surrogateAuthRequired": false, "enabled": true, "alwaysDisplayInConsole": false, "clientAuthenticatorType": "client-secret", "redirectUris": [ "https://mandant.squeeze.one/*" ], "webOrigins": [ "https://mandant.squeeze.one" ], "notBefore": 0, "bearerOnly": false, "consentRequired": false, "standardFlowEnabled": true, "implicitFlowEnabled": false, "directAccessGrantsEnabled": true, "serviceAccountsEnabled": false, "publicClient": true, "frontchannelLogout": false, "protocol": "openid-connect", "attributes": { "saml.force.post.binding": "false", "saml.multivalued.roles": "false", "oauth2.device.authorization.grant.enabled": "false", "backchannel.logout.revoke.offline.tokens": "false", "saml.server.signature.keyinfo.ext": "false", "use.refresh.tokens": "true", "oidc.ciba.grant.enabled": "false", "backchannel.logout.session.required": "true", "client_credentials.use_refresh_token": "false", "require.pushed.authorization.requests": "false", "saml.client.signature": "false", "id.token.as.detached.signature": "false", "saml.assertion.signature": "false", "saml.encrypt": "false", "saml.server.signature": "false", "exclude.session.state.from.auth.response": "false", "saml.artifact.binding": "false", "saml_force_name_id_format": "false", "acr.loa.map": "{}", "tls.client.certificate.bound.access.tokens": "false", "saml.authnstatement": "false", "display.on.consent.screen": "false", "token.response.type.bearer.lower-case": "false", "saml.onetimeuse.condition": "false" }, "authenticationFlowBindingOverrides": {}, "fullScopeAllowed": true, "nodeReRegistrationTimeout": -1, "protocolMappers": [], "defaultClientScopes": [ "web-origins", "profile", "roles", "email" ], "optionalClientScopes": [ "address", "phone", "offline_access", "microprofile-jwt" ], "access": { "view": true, "configure": true, "manage": true } } ``` ### Konfiguration in Squeeze In der Mandantenkonfiguration (s. [Server- und Mandantenkonfiguration](https://docs.squeeze.one/books/squeeze-2-admin-handbuch/page/server-und-mandantenkonfiguration "Server- und Mandantenkonfiguration")) sind folgende Parameter zu hinterlegen: - `defaultRoleIds` - Kommaseparierte Liste von Squeeze-Rollen-IDs, welche neuen, bisher unbekannten Usern gegeben werden. - `keycloak` - Konfiguration der Anbindung von Keycloak. Hiermit wird gesteuert, welcher Keycloak-Server und welcher Realm für die Authentifizierung dieses Mandanten zuständig ist. - `baseUrl` - URL des Keycloaks, der genutzt werden soll. - `realm` - Name des Realms, der genutzt werden soll. ```JSON "auth": { "oauth2": { "type": "keycloak", "defaultRoleIds": "1,2", "keycloak": { "baseUrl": "https://keycloak.k8s.staging.squeeze.one", "realm": "neuer-realm-name" } } } ``` # [internal] SSO mit Azure Active Directory (AAD)

Es wurde bereits die AAD mit Keycloak verbunden, um SSO zu ermöglichen. Bei Fragen bitte bei Fabian T. oder Friedrich B. melden. Für administrative Tätigkeiten im Keycloak Realm werden Admin-Rechte benötigt. Diese werden am besten auf die realen User vergeben, die (seitens Kunde oder Softwarebetreiber) ohnehin in Keycloak vorhanden sind.

### Prinzip Wenn sich User mittels Azure Active Directory bei unserer Software anmelden möchten, dann hinterlegen wir die AAD des Kunden bei uns im Keycloak als Identity Provider. Somit können wir weiterhin in Keycloak Konfigurationen ohne Zuarbeit des Kunden vornehmen und haben gleichzeitig keinen Overhead durch manuelle Pflege von Usern. ### Vorraussetzung Für SSO mittels AAD wird benötigt: - Ein Keycloak Server - Ein Keycloak Realm in den die User des Kunden synchronisiert werden sollen - Ein Admin User im Keycloak Realm oder ein allgemeiner Admin User im Master-Realm des Keycloak Servers. #### Konfiguration

Es ist ratsam die Dokumentation von Keycloak selbst zu lesen. Hier wollen wir keine redundante, ggf. langfristig obsolete Dokumentation pflegen: [https://www.keycloak.org/docs/latest/server\_admin/#\_identity\_broker\_oidc](https://www.keycloak.org/docs/latest/server_admin/#_identity_broker_oidc) (Neueste Keycloak Version) Diese Doku dokumentiert bereits die neue Web GUI von Keycloak, welche bei der DEXPRO noch nicht zum Einsatz kommt. Im Prinzip sind diese Konfigurationen gleich.

Das sind die Schritte, die initial zur Anbindung notwendig sind: 1. Kunden in seiner Azure Active Directory eine App Registration anlegen lassen (ähnlich wie bspw. auch bei Integration von Graph APIs notwendig). 2. In Keycloak im Realm des Kunden einen OpenIdConnect Identity Provider anlegen und die Credentials und Verbindungs URLs der AAD App übernehmen (Hierzu kann ein Metadata-Dokument übernommen werden, das müsste ein AAD Admin kennen: [https://login.microsoftonline.com/00000000-9c36-4c13-9f9e-f686123d07b5/v2.0/.well-known/openid-configuration](https://login.microsoftonline.com/00000000-9c36-4c13-9f9e-f686123d07b5/v2.0/.well-known/openid-configuration)) Wenn diese Konfigurationen korrekt gepflegt sind, dann können sich User der AAD in Keycloak mittels AAD anmelden. Somit ist wiederum der Login in Squeeze möglich. #### Client Secret aktualisieren

Client Credentials von AAD Apps laufen nach einiger Zeit ab. Im Standard handelt es sich um einige Monate. Diese Information hat der Kunde in der AAD und kann sie ebenfalls selbst konfigurieren.

Bei Kunden, die bereits eine konfigurierte SSO mit Azure AAD hinterlegt haben, ist es periodisch notwendig, dass das Client Secret, welches in Keycloak hinterlegt wird, erneuert wird. Das sind die notwendigen Schritte: - Der Kunde muss ein neues Client Secret bereitstellen. - Dieses Secret im betroffenen Keycloak Realm bei dem konfigurierten Identity Provider einsetzen. - Der Kunde sollte den Login testen. - Dazu nutzt man idealerweise einen Browser im privaten Modus und loggt sich neu über die AAD des Kunden ein. - Wenn man sich ganz sicher sein möchte, dass dies funktioniert, dann nutzt man für den Login einen User, der noch nicht in Keycloak bekannt ist (im Menü "Users" einsehbar). Dieser User müsste dann nach einem erfolgreichem Login verfügbar sein. # [internal] Azure-SSO für Support-Logins Sie können Azure als Identity Provider konfigurieren, damit Administratoren und Supporter sich in Squeeze anmelden können, ohne vorher einen User zu erstellen. ### Konfiguration der Azure App In Azure ist eine App zu registrieren, die für die Authentifizierung genutzt werden soll. #### Wildcards konfigurieren Damit nicht für jede Domain eine einzelne App registriert werden muss, können bis zu 256 Wildcard Domains hinterlegt werden. Die UI in Azure lässt die Konfiguration von Wildcards jedoch nicht zu, daher müssen wildcards über die Mainfest Datei der App definiert werden. Hier ein Beispiel des relevanten Bereichs: ```JSON { "replyUrlsWithType": [ { "url": "https://*.example.squeeze.one/ui/v1/support/", "type": "Web" }, { "url": "https://*.demo.squeeze.one/ui/v1/support/", "type": "Web" } ] } ``` ### Konfiguration Squeeze Wenn sie in Azure eine App Registrierung durchgeführt haben, dann reicht es 2 Konfigurationswerte in der Server- oder Mandantenkonfiguration hinzuzufügen: ```JSON { "auth": { "azure": { "clientId": "...", "secret": "..." } } } ``` Alternativ können Umgebungsvariablen genutzt werden, bspw. wenn die Anwendung mit Docker oder Linux betrieben wird: ``` SQZ_AUTH_AZURE_CLIENT_ID=... SQZ_AUTH_AZURE_SECRET=... ```

Bei Support-Login mittels Azure erhalten User automatisch Admin-Rechte im Squeeze-Mandanten.

### # Login mit Microsoft Mit der Squeeze Version 2.20 besteht die Möglichkeit des einfachen Logins mit Hilfe von Microsoft Entra ID auch bekannt als Azure AD. Auf dieser Seite wird beschrieben wie sie vorgehen können, um einen Login Button auf der Anmeldeseite von Squeeze anzeigen zulassen. Nach Abschluss der Konfiguration sieht die Anmeldeseite wie folgt aus: [![image-1750452730628.png](https://docs.squeeze.one/uploads/images/gallery/2025-06/scaled-1680-/image-1750452730628.png)](https://docs.squeeze.one/uploads/images/gallery/2025-06/image-1750452730628.png) ### Konfiguration in Microsoft Entra ID #### Erstellen Sie ein Microsoft Entra App für ihr Unternehmen

Die Redirect URL ist die URL Ihres Squeeze Tenants mit der zusätzlichen Pfadangabe /sso/ In diesen Beispiel ist es [https://private.squeeze.one/sso/](https://private.squeeze.one/sso/)

[![image-1750458259983.png](https://docs.squeeze.one/uploads/images/gallery/2025-06/scaled-1680-/image-1750458259983.png)](https://docs.squeeze.one/uploads/images/gallery/2025-06/image-1750458259983.png) #### Secret für die App erstellen [![image-1750454240101.png](https://docs.squeeze.one/uploads/images/gallery/2025-06/scaled-1680-/image-1750454240101.png)](https://docs.squeeze.one/uploads/images/gallery/2025-06/image-1750454240101.png)

Kopieren Sie das Secret. Beachten Sie, dass das Secret später nicht mehr eingesehen/kopiert werden kann.

[![image-1750457108362.png](https://docs.squeeze.one/uploads/images/gallery/2025-06/scaled-1680-/image-1750457108362.png)](https://docs.squeeze.one/uploads/images/gallery/2025-06/image-1750457108362.png) #### API-Berechtigungen festlegen [![image-1750458563590.png](https://docs.squeeze.one/uploads/images/gallery/2025-06/scaled-1680-/image-1750458563590.png)](https://docs.squeeze.one/uploads/images/gallery/2025-06/image-1750458563590.png) #### Client App-Id und Secret in Squeeze hinterlegen [![image-1750458828617.png](https://docs.squeeze.one/uploads/images/gallery/2025-06/scaled-1680-/image-1750458828617.png)](https://docs.squeeze.one/uploads/images/gallery/2025-06/image-1750458828617.png)