External Identity Providers
The Authorization Server can be configured to use an external identity provider (IDP), such as Keycloak, to authenticate users. An external IDP cannot be used to handle client credentials or custom grant types. It can only be used to handle the authorization code grant type.
For an external IDP to work, it must implement the OIDC specification and support the authorization code flow.
The Authorization Server integrates into the external IDP via the .NET Microsoft.AspNetCore.Authentication.OpenIdConnect
package, using AddOpenidConnect
.
Only Open ID Connect is supported. Other authentication mechanisms, such as, SAML, are not supported.
The identity provider can be configured via the TCG Authorization Server Web UI.
Claims Required from the External IDP
Independent of what identity provider is used, it must provide at minimum the following claims in its ID token or via the userinfo endpoint:
sub
: for the unique user ID, MUST BE in both the ID token and the user info response, see OIDC specification- name claim: for the user's display name, configurable.
- username claim: for the user's username
Claim Required by the Platform
The reason why we provide a custom Authorization Server is for guaranteeing for all applications in this eco-system some authorization defaults.
For example, you can theoretically use any sort of string to adorn a user with permissions to do something.
Some systems provide them as a role
, others as roles
, yet others as http://schemas.microsoft.com/ws/2008/06/identity/claims/role
or http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid
.
To relieve resource services and other applications in this eco-system from guessing and too many configuration options, some defaults must be provided among the claims of authenticated users. These defaults date back from when the platform was still tightly coupled to windows. The following defaults must be honored to ensure the relationship to the Authorization Server to work:
- A unique user ID is a claim of type
sub
- For backwards compatibility (3.1.0 or earlier), this claim is also present as
http://schemas.microsoft.com/ws/2008/06/identity/claims/primarysid
- This claim is used to remember which user locked a process for editing
- For backwards compatibility (3.1.0 or earlier), this claim is also present as
- The username of the user is a claim of type
username
- The username is often used when assigning an entity to a particular user. We assume that the used external authentication realms do not collide in a way that the same username belongs to 2 different users.
- The display name of the user is a claim of type
name
- For backwards compatibility (3.1.0 or earlier), this claim is also present as
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name
- The name is used for displaying purpose of the user name on top of the web sites
- For backwards compatibility (3.1.0 or earlier), this claim is also present as
- Roles of the user are claims of type
role
- For backwards compatibility (3.1.0 or earlier), this claim is also present as
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid
- The roles are used to give users access permissions, for example, to access particular processes and activities
- To give access to only a single user, the unique user ID can be used
- For backwards compatibility (3.1.0 or earlier), this claim is also present as
Configuring the Service to Use an External Identity Provider
External identity providers can comfortably be configured via the Authorization Server Web UI by any administrator. The configuration data is stored in the database and encrypted at rest with the data protection subsystem provided by .NET. The Authorization Server provides integrated support for periodically fetching roles from Entra ID and Keycloak 19 - 21.
Important Any change regarding external IDP configuration requires a service restart.
The external IDP must be configured to allow the Authorization Server to delegate authentication calls to it. This requires usually at minimum the following:
- A registered application or client for the external IDP. A
client ID
in OIDC terms. - A client secret (depends on external IDP)
- A redirect URI that the external IDP will send its code response to.
The redirect URI for the Authorization Server is
https://<auth_service>/signin-oidc
, for examplehttps://auth.contoso.com/signin-oidc
if you host the Authorization Server onauth.contoso.com
. Note that many external IDPs require HTTPS.
The following values must be available to be able to configure the Authorization Server:
- IDP name: used to display the sign-in button and must not be empty.
- Authority URL: a URL that is the base path of the external IDP's OIDC endpoints.
- Metadata address: only required if it is not using a standard route behind the Authority URL
- Client ID: The client ID that was created on the external IDP
- Client secret: in case a confidential client is used and you want to automatically fetch roles available on the external IDP
- User name claim type: the claim type that the external IDP writes the user name to
- Name claim type: the claim type that the external IDP writes the user's display name to
- Role claim type: the claim type that the external IDP writes the user's roles to
Additionally, you can define whether or not to
- require HTTPS endpoints for the external IDPs OIDC endpoints. It is recommend to require HTTPs endpoints.
- get additional claims from the user info endpoint, in case not all user claims are sent with the ID token
- disable automatic role discovery, in case you do not want the Authorization Server to periodically fetch and store roles that are available via the external IDP
- map custom claims, for example when you want to give certain users a specific role
- Define sign-in scopes, if the sign-in to the external IDP uses specific scopes
Configuring Claim Mappings
At the end of the configuration of the external identity provider, a list of custom claim mappings can be defined.
They allow, for example, to map particular users to specific roles, or to assign a standard role to every user,
substituting for the Everyone
SID claim that users signed in via Active Directory receive.
The configuration understands 4 parameters:
- Source claim type: The claim type (for example,
role
orpreferred_username
) of the claim that the external IDP provides. Can be left empty if it defaults to the default role claim type. - Source claim values: A space separated list of claims, used as individual regex expressions.
- Target claim type: The claim type of the target value. Can be left empty if it defaults to the default role claim type.
- Target claim value: A claim that an authenticated user that matches the source type and value receives.
In most cases, the target claim type can be omitted since this feature is generally aimed at giving users additional roles.
Example: Assign the role 'everyone' to every user
The following configuration assigns the role everyone
to every user that authenticates via the external IDP.
- Leave the source and target claim types empty.
- Set the source claim value to
.*
. - Set the target claim value to
everyone
.
Example: Assign the role 'administrator' to specific users (Entra ID)
The following configuration assigns the role administrator
to the users with the usernames [email protected], [email protected]
and all users that are suffixed with [email protected] (like [email protected]).
- Set the source claim type to
preferred_username
. - Set the source claim value to
[email protected] .*[email protected] kevin\[email protected]
- Set the target claim value to
administrator
Examples
Here we provide sample configurations for the Authorization Server to add either Keycloak or Entra ID as an external IDP.
Example: Use Microsoft Entra ID as an External Identity Provider
If you have not yet prepared Entra ID to be used as an authentication provider (for example, you have not yet registered any application), this documentation has a dedicated section that explains all required steps to set up Entra ID integration in detail.
If you already have client ID and secret, then simply follow these steps:
- Log in as local administrator to the Authorization Server
- Click on the "Identity Providers" tab
- Click on "Add Entra ID"
-
Enter your configuration data. In this example, the following data is sufficient:
json { "Name": "EntraID", "Authority": "https://login.microsoftonline.com/<tenant_guid>/v2.0", // MetadataAddress is not required since it uses the default path behind the Authority URL // "MetadataAddress": "https://login.microsoftonline.com/<tenant_guid>/v2.0/.well-known/openid-configuration", "ClientId": "<registered application (client) id>", "ClientSecret": "<registered application secret>", "UsernameClaimType": "preferred_username", "RoleClaimType": "roles", "NameClaimType": "name", }
-
Optionally add custom claim mappings
- Click "Create" and restart the Authorization Server
Example: Use Keycloak as an External Identity Provider
This example below uses a local Keycloak installation on Docker. In real scenarios, the URL is not localhost and uses https.
- Log in as local administrator to the Authorization Server
- Click on the "Identity Providers" tab
- Click on "Add Keycloak"
-
Enter your configuration data. In this example, the following data is sufficient:
json { "Name": "Keycloak", "Authority": "http://localhost:8080/realms/master", // MetadataAddress is not required since it uses the default path behind the Authority URL //"MetadataAddress": "http://localhost:8080/realms/master/.well-known/openid-configuration", "ClientId": "oidc-code-pkce", "ClientSecret": "87pdXsjOO749Z2s9hO3iq3c3TydcF6vJ", "UsernameClaimType": "preferred_username", "RoleClaimType": "role", "NameClaimType": "name", "RoleDiscoveryBaseURL": "http://localhost:8080/admin/realms/master/" }
-
Optionally add custom claim mappings
- Click "Create" and restart the Authorization Server
Troubleshooting Permissions or Claims Given By External IDPs
As explained at the beginning of this chapter, it is important that th external IDP provides the required claims.
If the external IDP, for example, does include roles in the ID token or via the user info endpoint, the authenticated user also does not have any roles.
The Authorization Server shows you the claims of the current user on the main page if you set the appsettings.production.json
setting Service:ShowClaimsOnHome
to true
.
Knowing this list of claims helps to fine-tune the integration into the external IDP.
Keycloak, for example, does not send any roles with a freshly pulled up docker container (quay.io/keycloak/keycloak:20.0.1
).
To get roles for a user authenticated by Keycloak, you have to change Keycloak configuration first.
- Click on
Client Scopes
, then edit theroles
scope. - Click on
Mappers
, add a mapperby configuration
, select theUser Client Role
mapper type. - Choose a name, leave the
Client ID
empty and set theToken Claim Name
torole
orroles
, and ensureAdd to ID Token
is selected. - Repeat the login into the Authorization Server, your user now has claims derived from his Keycloak roles.
For further finetuning and Keycloak configuration, we have to defer you to Keycloak documentation or to a Keycloak consultant of your choice.
Troubleshooting redirect URIs
The Authorization Service sends a redirect URL to the external IDP so that users can perform the authorization code flow with PKCE. The redirect URIs are usually case sensitive, but that is ultimately decided by the IDP, so results may differ. Read up on the requirements of your external IDP and verify that the redirect URI matches the exact casing.