Identity Provider (IDP)
Der CMI STS kann externe Identity Provider (IDP) anbinden, um den Login-Prozess an diesen zu delegieren. Dazu muss der IDP ein vom CMI STS unterstütztes Protokoll verwenden.
IDPs werden pro Mandanten in einer benannten Liste in ExternalIdps
konfiguriert. Der Name, bzw. die ID eines IDP kann frei gewählt werden. Für jeden IDP muss die Eigenschaft Type
gesetzt werden um anzugeben, welches Protokoll der IDP verwendet. Es werden weitere Eigenschaften benötigt, die vom Protokoll abhängig sind.
"tenants": {
"mandant": {
"ExternalIdps": {
"auth0": { // "auth0" ist die frei gewaehlte ID des ersten IDPs
"Type": "Oidc", // Protokoll des IDPs
// ... weitere Eigenschaften
},
"adfs": { // "adfs" ist die frei gewaehlte ID des zweiten IDPs
"Type": "Wsfed", // Protokoll des IDPs
// ... weitere Eigenschaften
}
}
}
}
Home Realm Discovery (HRD)
Das HRD ist ein Prozess mit dem ein Security Token Service entscheidet, mit welchem IDP ein Benutzer authentifiziert werden soll. Diese Bezeichnung wird vor allem von Microsoft verwendet. Im Kontext des CMI STS sind dies die Selektoren (siehe "Automatische Wahl der Identity Provider"). Standardmässig werden einem Benutzer alle externen Identity Provider angezeigt.
Anforderungen
Damit der CMI STS mit einem IDP zusammen arbeiten kann, muss er folgende Anforderungen erfüllen:
OIDC, WSFed: Der Identity-Provider muss mindestens einen dieser beiden Claim-Typen liefern. Der Claim-Wert wird vom CMI STS als eindeutige Benutzer-ID verwendet:
- sub (Subject)
- http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier
OIDC: Der Identity-Provider sollte den Claim-Typen sid (Session Id) liefern, um einen sauberen Logout-Prozess zu ermöglichen.
WS Federation Provider
Hinweis: CMI empfiehlt die Verwendung des OIDC-Protokolls, wann immer das möglich ist.
Zur Konfiguration eines WS Federation Providers stehen grundsätzlich alle Optionen zur Verfügung, die das ASP.NET Core Framework bereitstellt.
Die folgende Konfiguration zeigt eine beispielhafte minimale Konfiguration, die für die meisten Provider ausreichend ist.
"o365": {
"Type": "WsFed",
"MetadataAddress": "https://login.microsoftonline.com/[...]/2007-06/federationmetadata.xml",
"Wtrealm": "https://schwerzenwil.ch/00000000-0000-0000-0000-000000000000",
"IdClaimType": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
}
Type
(erforderlich): Die Type-ID für WsFederation lautetWsFed
.MetadataAddress
(erforderlich): Die URL unter der Metadaten abgerufen werden können, wird durch den IDP festgelegt und wird hierhin übertragen.Wtrealm
(erforderlich): Eine URI die durch den IDP festgelegt und hierhin übertragen wird. Anhand des Wtrealms identifiziert der IDP den CMI STS.CallbackPath
(optional, Standardwert:/signin-wsfed-{Mandanten Id}-{IDP Id}
): Eine (relative) URL, auf die der IDP den Benutzer zurück auf den CMI STS umleiten soll, nach dem die Anmeldung am IDP erfolgreich durchgeführt wurde (Wreply).- Wenn der Pfad konfiguriert wird, muss dieser eindeutig für alle konfigurierten IDPs sein.
- Der CallbackPath wird automatisch generiert, wenn keine Konfiguration vorhanden ist. Wenn die Mandanten-ID schwerzenwil und die IDP-ID o365 lautet, wird der Pfad /signin-wsfed-schwerzenwil-o365 erzeugt.
- Bei einigen IDPs muss der CallbackPath zu den erlaubten Redirect-/Umleitungs-URLs hinzugefügt werden:
https://<CMI STS Basis Url>/<Mandant>/identity/<CallbackPath>
Beispiel: https://sts.gemeinde.ch/schwerzenwil/identity/signin-wsfed-schwerzenwil-o365 IdClaimType
: Der Claim der für das Mapping des externen Benutzers auf einen CMI Benutzer verwendet wird. Der Debug-Log-Level schreibt die empfangenen Claims auf das Log. So lässt sich erkennen, wie der vom IDP ausgestellte Claim-Type lautet.
OpenID Connect Provider
Zur Konfiguration eines OpenID Connect Providers stehen grundsätzlich alle Optionen zur Verfügung, die das ASP.NET Core Framework bereitstellt.
Die folgende Konfiguration zeigt eine beispielhafte minimale Konfiguration, die für die meisten Provider ausreichend ist.
"auth0": {
"Type": "Oidc",
"ResponseType": "code",
"ClientId": "...",
"ClientSecret": "...",
"Authority": "https://cmiag.eu.auth0.com",
"MetadataAddress": "https://login.microsoftonline.com/xxx.xxx.xx.x/v2.0/.well-known/openid-configuration",
"CallbackPath": "/signin-oidc-auth0",
"SignedOutCallbackPath": "/signout-callback-oidc-auth0",
"Scope": [ "openid", "profile", "email", "phone", "address" ],
"IdClaimType": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
}
Type
(erforderlich): Die Type-ID für OpenID Connect Provider lautetOidc
.ResponseType
(optional, Standardwert:id_token
): Legt den Response Type fest, den der CMI STS beim IDP anfordert. Es gibt folgende Optionen:code
: Für die Kommunikation mit dem IDP empfiehlt CMI wenn immer möglich den AuthorizationCode-Flow. Dieser Flow benötigt ein Client Secret.id_token
: Standardmässig wird der Implicit Flow verwendet. Dieser Flow hat Schwächen und sollte nicht verwendet werden.ClientId
(erforderlich): Die Client ID wird durch den IDP festgelegt und wird hierhin übertragen.ClientSecret
- Wenn
ResponseType=code
(erforderlich): Das Secret wird durch den IDP festgelegt und wird für den Authorization Code Flow benötigt. Mit diesem Secret authentifiziert sich der CMI STS gegenüber dem IDP. - Wenn
ResponseType=id_token
(ohne Wirkung): Der Implicit Flow verwendet kein Secret. - *
Authority
(optional): Die Authority wird durch den IDP festgelegt und legt fest, unter welcher URL der CMI STS den IDP kontaktieren kann. - *
MetadataAddress
(optional): Die Meta-Daten-Adresse wird durch den IDP festgelegt und legt fest, unter welcher URL der CMI STS den IDP kontaktieren kann. CallbackPath
(optional, Standardwert:/signin-oidc
): Der Callback-Path teilt dem IDP mit, auf welche CMI STS URL er den Benutzer weiterleiten soll, nach dem der IDP den Benutzer authentifiziert hat. Der Callback-Path kann beliebig festgelegt werden, solange der Callback-Path eindeutig ist. Somit muss, wenn mehr als ein Oidc-IDP verwendet wird, der Callback-Path in jedem Fall festgelegt werden.SignedOutCallbackPath
(optional, Standardwert:/signout-callback-oidc
): Der Callback-Path teilt dem IDP mit, auf welche CMI STS URL er den Benutzer weiterleiten soll, nach dem der IDP den Benutzer abgemeldet hat. Der Callback-Path kann beliebig festgelegt werden, solange der Callback-Path eindeutig ist. Somit muss, wenn mehr als ein Oidc-IDP verwendet wird, der Callback-Path in jedem Fall festgelegt werden.Scopes
(optional, Standardwert:openid, profile
): Liste der Scopes aufgrund dessen der IDP Claims für den Benutzer ausstellt. Der IDP wird den Benutzer möglicherweise nach einem Einverständnis (Consent) fragen, bevor die Claims ausgestellt und an den CMI STS übertragen werden. Siehe hierzu auch Scopes und Ressourcen. Die Scopesopenid
undprofile
sind in jedem Fall erforderlich.IdClaimType
: Der Claim der für das Mapping des externen Benutzers auf einen CMI Benutzer verwendet wird. Der Debug-Log-Level schreibt die empfangenen Claims auf das Log. So lässt sich erkennen, wie der vom IDP ausgestellte Claim-Type lautet.
* Entweder eine Authority
oder eine MetadataAddress
muss spezifiziert werden. Eine der beiden Informationen muss bekannt sein, damit der IDP verwendet werden kann.
Mehrere Issuer / OpenID Multitenant Azure AD
Wird ein IDP verwendet der mehrere Issuer unterstützt, wie z.B. Azure AD mit Gastbenutzern, muss die Authority
auf einen "wildcard" Tenant wie organizations gestellt werden. Die einzelnen Issuer werden als separate Liste in ValidIssuers
gepflegt.
"azuread": {
// ... weitere Eigenschaften
"Authority": "https://login.microsoftonline.com/organizations/v2.0",
"TokenValidationParameters": {
"ValidIssuers": ["https://login.microsoftonline.com/{tenantid1}/v2.0", "https://login.microsoftonline.com/{tenantid2}/v2.0"]
// ... weitere Eigenschaften
}
}
Windows Authentication
Sie können die Windows-Authentifizierung verwenden, wenn der Server in einem Unternehmensnetzwerk mit Active Directory Domänen Identitäten oder Windows-Konten ausgeführt wird, um Benutzer zu identifizieren. Die Windows-Authentifizierung eignet sich für Intranetumgebungen, in denen Benutzer, Client-Apps und Webserver derselben Windows-Domäne angehören.
Wenn Client-Apps ausserhalb des Intranets authentifiziert werden sollen, kann die Windows-Authentifizierung nicht verwendet werden.
Wichtig: Die aktuelle Implementierung im CMI STS unterstütz diese Authentifizierung derzeit nur, wenn der CMI STS mit dem Webserver IIS betrieben wird. Die Authentifizierung wird durch den IIS und die im CMI STS aktivierte IIS-Middleware durchgeführt. Die LDAP-Middleware ist nicht aktiviert, so dass unter Linux und macOS der CMI STS keine Authentifizierung gegen einen Verzeichnisdienst durchführt werden kann.
Wichtig: Die Windows Authentifizierung wurde nur mit dem Webserver IIS getestet. Das Feature wird unter HTTP.sys und Kestrel nicht von CMI unterstützt.
Wichtig: Die Windows-Authentifizierung kann nicht in Kombination mit den Android- und iOS-Apps CMI Sitzungen und Dossierbrowser verwendet werden.
Der IDP Windows erscheint automatisch zur Auswahl im Login-Dialog, wenn der Webserver die Authentifizierung via NTLM oder Kerberos anbietet.
Der Artikel Windows Authentication \<windowsAuthentication> beschreibt, wie die Windows Authentifizierung aktiviert wird. Grundsätzlich sind folgende Schritte erforderlich:
- In den Windows Server Rollen das Feature Windows Authentication für den IIS installieren. Möglicherweise ist ein Serverneustart erforderlich.
- In der Datei web.config des CMI STS das Attribut
enabled
vonwindowsAuthentication
auftrue
stellen.anonymousAuthentication
sollte dabei nicht deaktiviert werden, um auch weiterhin andere Authentifizierungsmethoden zu ermöglichen.
<location path=".">
<system.webServer>
<security>
<authentication>
<anonymousAuthentication enabled="true" />
<windowsAuthentication enabled="true" />
</authentication>
</security>
</system.webServer>
</location>
Selektoren können weiterhin angewendet werden. Der Client webAppClient sollte nicht mit dem Windows-Provider authentifiziert werden, da die Android- und iOS-Apps dies nicht unterstützen. Das folgende Konfigurationsbeispiel verwendet für den Client webAppClient das BuiltIn-Login, während andere Clients automatisch mit Windows authentifiziert werden.
"tenants": {
"mandant": {
"ExternalIdpSelectors": [
{
"Clients": ["webAppClient"],
"NetworkRanges": ["0.0.0.0/0"],
"Providers": ["metatool"]
},
{
"NetworkRanges": ["0.0.0.0/0"],
"Providers": ["Windows"]
}
]
}
}
Weitere Informationen zur Windows Authentifizierung beinhaltet der Artikel Configure Windows Authentication in ASP.NET Core.
Subject und Claims
Wichtig: Alle in diesem Abschnitt beschrieben Konfigurationen haben keine Wirkung auf den eigentlichen Authentifizierungsprozess. Die Authentifizierung wird durch den IIS und die im CMI STS aktivierte IIS-Middleware durchgeführt. Die Konfiguration legt nur fest, wie weitere Eigenschaften des bereits authentifizierten Benutzers beim Verzeichnisdienst abgefragt werden und wie diese Eigenschaften verwendet werden.
Der CMI STS fügt nach der Authentifizierung Claims hinzu, in dem der Benutzer im Verzeichnisdienst abgefragt wird und dessen Eigenschaften übertragen werden. Ist die Abfrage nicht erfolgreich, wird die Authentifizierung abgebrochen. Die Claims können für das Feld- und Gruppenmapping verwendet werden.
- Es werden die Claims
name
,given_name
,family_name
,middle_name
,email
,email_verified
,phone_number
,home_directory
,home_drive
,x500distinguishedname
,employee_id
,sam
,upn
undsid
ausgestellt, sofern ein Wert im Verzeichnisdienst vorhanden ist. - Alle Gruppenmitgliedschaften werden im Claim
role
eingetragen. Gruppenmitgliedschaften werden nicht rekursiv ermittelt. - Die Benutzer-ID (subject,
sub
) wird abhängig von der Konfiguration festgelegt. SieheSubjectProperty
.
Der Vorgang kann optional konfiguriert werden:
{
"Tenants": {
"mandant": {
"ExternalIdps": {
"windows": {
"Type": "Windows",
"SubjectProperty": "UserPrincipalName",
"ContextType": "Domain",
"ContextName": "contoso.local",
"GroupMembershipResolveLimit": 50
}
}
}
}
}
Wichtig: Derzeit wird nur ein externer IDP mit dem Typ Windows unterstützt. Sind mehrere vorhanden, wird nur die erste Konfiguration verwendet.
SubjectProperty
(optional, Standardwert:UserPrincipalName
): Legt fest, anhand welcher Eigenschaft der Benutzer eindeutig identifiziert wird. Diese Eigenschaft wird für den Claim sub (subject) verwendet. Gültige Werte sind:SamAccountName
, Security Account Manager (SAM) nameName
UserPrincipalName
, User Principal Name (UPN)DistinguishedName
, Distinguished Name (DN)Sid
, Security Identifier (SID)Guid
, Globally Unique Identifier (GUID)Email
ContextType
(optional, Standardwert:Domain
): Legt den Typ der Verzeichnissuche fest. Gültige Werte sind:Machine
, der lokale SAM-Speicher des WebserversDomain
, die Windows-Domäne (AD DS)ApplicationDirectory
, die Windows-Domäne (AD LDS)ContextName
(optional, Standardwert: Domäne des Benutzers, der den CMI STS Prozess betreibt): Name des Verzeichnisdienstes / Domäne, die abgefragt werden soll.GroupMembershipResolveLimit
(optional, Standardwert: 50): Maximale Anzahl der Gruppen, die in den Claimrole
übertragen werden. Ein JWT-Token kann nicht beliebig lang werden. Eine grosse Anzahl von Gruppenmitgliedschaften kann das Limit übersteigen. Wenn kein Gruppenmapping verwendet wird, kann ein Wert <1 eingetragen werden. In diesem Fall wird der Claimrole
nicht ausgestellt. Die Gruppen werden alphabetisch sortiert, bevor überzählige Gruppen entfernt werden.
Wichtig: SAM und Name in
SubjectProperty
sind nur innerhalb einer Domäne eindeutig. Ist ein Domain-Trust, ein Domain-Tree oder eine andere Variante von externen Principals vorhanden, sollen diese Identifier nicht verwenden werden. Die Email ist möglicherweise nicht eindeutig oder nicht vorhanden. CMI empfiehlt die Verwendung der UPN. Dieser ist für Menschen lesbar und über Domänengrenzen hinweg eindeutig. DN, SID und GUID erfüllen die Eindeutigkeit auch, sind jedoch nicht so lesbar.
Logos
Stehen mehrere Login-Möglichkeiten zur Verfügung, werden die IDP mit ihrem Namen aufgelistet. Wenn eine Grafik im SVG-Format verfügbar ist, wird diese Grafik anstatt dem IDP-Namen verwendet.
Die Grafik wird im Verzeichnis wwwroot/img/ipd/\<provider name>.svg gesucht. Die Provider-Name entspricht dem Namen, der in der Konfiguration verwendet wird.
Beispiel:
wwwroot/img/ipd/azure.svg
{
"Tenants": {
"mandant": {
"ExternalIdps": {
"azure": {}
}
}
}
}
Ein alternatives Verzeichnis kann konfiguriert werden, aus dem Logos geladen werden sollen. Die Konfiguration kann global für alle Mandanten oder pro Mandant festgelegt werden. Das Logo wird mit folgender Priorität ausgewählt:
- Aus dem mandanten-spezifischen alternativen Logo-Verzeichnis
- Aus dem global konfigurierten alternativen Logo-Verzeichnis
- Aus dem Verzeichnis wwwroot/img/ipd/
- Wird keine SVG-Datei mit dem IDP-Namen gefunden, wird kein Logo angezeigt
{
"UiCustomization": {
"IdpLogoDirectory": "C:\\idp\\global"
},
"Tenants": {
"mandant": {
"UiCustomization": {
"IdpLogoDirectory": "C:\\idp\\mandant"
},
"ExternalIdps": {
"azure": {}
}
}
}
}
UiCustomization.IdpLogoDirectory
(optional, Standardwert:null
): Verzeichnis in dem nach SVG-Dateien für einen IDP gesucht werden soll. Unterverzeichnisse werden nicht berücksichtigt. Nicht existierende Verzeichnisse werden ignoriert. Es wird empfohlen einen absoluten Pfad zu verwenden.
Alternativer ID-Claim
Einen Benutzer im CMI werden sog. Externe Benutzer zugeordnet. Ein externer Benutzer besitzt die Eigenschaften Provider ID und Benutzer Id. Um einen Benutzer vom IDP einem CMI Benutzer zuzuordnen, wird ein ID-Claim der vom IDP ausgestellt wurde, mit der Benutzer Id verglichen.
Standardmässig wird der Claim sub oder http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier als ID-Claim verwendet, um den Benutzer im CMI zu identifizieren.
OIDC, WSFed, Windows: Ein alternativer ID-Claim kann mit der Option IdClaimType
festgelegt werden. Hat der IDP keinen Claim mit dem angegebenen Typen ausgestellt, wird der Login-Prozess abgebrochen.
Achtung: Es ist möglich, einen Claim anzugeben, der nicht eindeutig ist. Hat mehr als ein Benutzer für den angegeben Claim den selben Wert, werden diese Benutzer im CMI als der selbe Benutzer erkannt.
Das folgende Beispiel konfiguriert den IDP mit der Provider-ID openid und den ID-Claim name. Im CMI ist ein passender externer Benutzer hinterlegt.
"openid": {
"Type": "Oidc",
"IdClaimType": "name"
...
}
Provider SignOut
Wenn sich ein Benutzer abmeldet, wird er zum CMI STS umgeleitet, der die Abmeldung vornimmt. Hat sich der Benutzer über einen IDP angemeldet, wird der Benutzer nur vom CMI STS abgemeldet, jedoch nicht beim IDP.
Web Client: Wenn "Automatische Wahl der Identity Provider" verwendet wird, hat dies zur Folge, dass der Benutzer nach der Abmeldung möglicherweise sofort wieder angemeldet wird. Nach der Abmeldung wird der Benutzer zurück zur ursprünglichen Anwendung umgeleitet. Die Anwendung bemerkt, dass der Benutzer nicht mehr angemeldet ist und leitet auf den CMI STS um, der wiederum eine automatische Weiterleitung am dem IDP durchführt. Da der Benutzer beim IDP nicht abgemeldet ist, erhält der CMI STS ein ID Token, ohne dass der Benutzer selbst eine Aktion tätigen muss und der Benutzer wird wieder angemeldet.
Wenn eine Abmeldung auch beim IDP erfolgen soll, kann dies explizit für den IDP aktiviert werden.
Achtung: Wenn sich der Benutzer bei anderen Anwendungen mit dem selben IDP angemeldet hat, wird er möglicherweise auch bei diesen Anwendungen abgemeldet.
WsFed:
- Die Option
UseProviderSignOut
muss den Werttrue
haben. - Der IDP muss die Redirect-Uri
https://<CMI STS Basis Url>/<Mandant>/identity/Account/Logout
akzeptieren.
"wsfed": {
"Type": "Wsfed",
"UseProviderSignOut": "true"
...
}
OIDC:
- Die Option
UseProviderSignOut
muss den Werttrue
haben. - Die Option
SignedOutRedirectUri
muss auf eine Logout-Uri konfiguriert werden, die durch den IDP bestimmt wird. Der Benutzer wird nach der Abmeldung am CMI STS auf diese Url umgeleitet.
"openid": {
"Type": "Oidc",
"UseProviderSignOut": "true",
"SignedOutRedirectUri": "<IDP spezifische Logout-Url>"
...
}