SSO with AD FS

In this guide, you will learn how to configure SAML single sign-on (SSO) with Active Directory Federation Services (AD FS).

👍

Request an SSO Setup

Follow this link to directly request an SSO setup for your workspace(s)

👍

Attention

Please make sure to read the general SSO guide first. The general process is defined there, while this page gives configuration details for ADFS.

Initial Setup

Setup SSO using Active Directory with AD FS and SAML

LeanIX supports Single sign-on (SSO) logins through SAML 2.0. A SAML 2.0 identity provider (IDP) can take many forms, one of which is a self-hosted Active Directory Federation Services (AD FS) server. AD FS is a service provided by Microsoft as a standard role for Windows Server that provides a web login using existing Active Directory credentials.

The LeanIX SAML Service Provider (SP) is based on Shibboleth. Therefore this documentation by Microsoft explains how to set up an AD FS federation with Shibboleth.

🚧

Attention

The linked documentation contains a description how to install Shibboleth. That can be skipped here as Shibboleth is provided as SP by LeanIX.

Usually, the AD FS metadata information can be found at the following URL: https\://\<IDP-URL>/FederationMetadata/2007-06/FederationMetadata.xml.

Mapping attributes

Map attributes from Active Directory with AD FS and SAML

When using SAML login with AD FS, you can pass values in addition to the authentication values. Here we describe how to pass a user's first name, last name, email, and role to LeanIX. See our documentation on attribute mapping for details. These values are defined as Claim Rules in the Relying Party Trust. To edit the Claim Rules, select the Relying Party Trusts folder from AD FS Management, and choose Edit Claim Rules from the Actions sidebar.

In order to properly configure the attribute mapping, custom claim rules need to be configured. The following example rules help to configure your AD FS federation with LeanIX. Thanks to the support of a very nice LeanIX customer who shared his insights and helped out others.

@RuleName = "Get tokenGroups"
c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", Issuer == "AD AUTHORITY"]
 => add(store = "Active Directory", types = ("http://claims.contoso.com/tokenGroups"), query = ";tokenGroups;{0}", param = c.Value);

@RuleName = "Add Given-Name from AD"
c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", Issuer == "AD AUTHORITY"]
 => add(store = "Active Directory", types = ("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"), query = ";givenName;{0}", param = c.Value);

@RuleName = "Add Surname from AD"
c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", Issuer == "AD AUTHORITY"]
 => add(store = "Active Directory", types = ("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname"), query = ";sn;{0}", param = c.Value);

@RuleName = "Add UPN from AD"
c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", Issuer == "AD AUTHORITY"]
 => add(store = "Active Directory", types = ("http://claims.contoso.com/ADupn"), query = ";userPrincipalName;{0}", param = c.Value);

@RuleName = "Add E-Mail-Address from AD"
c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", Issuer == "AD AUTHORITY"]
 => add(store = "Active Directory", types = ("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"), query = ";mail;{0}", param = c.Value);

@RuleName = "Send Given-Name as firstname"
c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"]
 => issue(Type = "firstname", Value = c.Value, Issuer = c.Issuer, Properties["http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/attributename"] = "urn:oasis:names:tc:SAML:2.0:attrname-format:uri");

@RuleName = "Send Surname as lastname"
c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname"]
 => issue(Type = "lastname", Value = c.Value, Issuer = c.Issuer, Properties["http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/attributename"] = "urn:oasis:names:tc:SAML:2.0:attrname-format:uri");

@RuleName = "Send ADUPN as uid"
c:[Type == "http://claims.contoso.com/ADupn"]
 => issue(Type = "uid", Value = c.Value, Issuer = c.Issuer, Properties["http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/attributename"] = "urn:oasis:names:tc:SAML:2.0:attrname-format:uri");

@RuleName = "Send E-Mail-Address as mail"
c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"]
 => issue(Type = "mail", Value = c.Value, Issuer = c.Issuer, Properties["http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/attributename"] = "urn:oasis:names:tc:SAML:2.0:attrname-format:uri");

@RuleName = "Send role ADMIN"
EXISTS([Type == "http://claims.contoso.com/tokenGroups", Value == "EAM-ADMIN"])
 => issue(Type = "role", Value = "ADMIN", Properties["http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/attributename"] = "urn:oasis:names:tc:SAML:2.0:attrname-format:uri");

@RuleName = "Send role MEMBER"
EXISTS([Type == "http://claims.contoso.com/tokenGroups", Value =~ "^EAM-MEMBER*"])
 => issue(Type = "role", Value = "MEMBER", Properties["http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/attributename"] = "urn:oasis:names:tc:SAML:2.0:attrname-format:uri");

@RuleName = "Send customerRoles MEMBER_CUSTOMERROLE1"
EXISTS([Type == "http://claims.contoso.com/tokenGroups", Value == "EAM-MEMBER-CUSTOMERROLE1"])
 => issue(Type = "customerRoles", Value = "MEMBER_CUSTOMERROLE1", Properties["http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/attributename"] = "urn:oasis:names:tc:SAML:2.0:attrname-format:uri");

@RuleName = "Send customerRoles MEMBER_CUSTOMERROLE2"
EXISTS([Type == "http://claims.contoso.com/tokenGroups", Value == "EAM-MEMBER-CUSTOMERROLE2"])
 => issue(Type = "customerRoles", Value = "MEMBER_CUSTOMERROLE2", Properties["http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/attributename"] = "urn:oasis:names:tc:SAML:2.0:attrname-format:uri");

@RuleName = "Send customerRoles MEMBER_CUSTOMERROLE3"
EXISTS([Type == "http://claims.contoso.com/tokenGroups", Value == "EAM-MEMBER-CUSTOMERROLE3"])
 => issue(Type = "customerRoles", Value = "MEMBER_CUSTOMERROLE3", Properties["http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/attributename"] = "urn:oasis:names:tc:SAML:2.0:attrname-format:uri");

@RuleName = "Send role VIEWER"
EXISTS([Type == "http://claims.contoso.com/tokenGroups", Value =~ "^EAM-VIEWER*"])
 => issue(Type = "role", Value = "VIEWER", Properties["http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/attributename"] = "urn:oasis:names:tc:SAML:2.0:attrname-format:uri");

@RuleName = "Send customerRoles VIEWER_CUSTOMERROLE1"
EXISTS([Type == "http://claims.contoso.com/tokenGroups", Value == "EAM-VIEWER-CUSTOMERROLE1"])
 => issue(Type = "customerRoles", Value = "VIEWER_CUSTOMERROLE1", Properties["http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/attributename"] = "urn:oasis:names:tc:SAML:2.0:attrname-format:uri");

@RuleName = "Send customerRoles VIEWER_CUSTOMERROLE2"
EXISTS([Type == "http://claims.contoso.com/tokenGroups", Value == "EAM-VIEWER-CUSTOMERROLE2"])
 => issue(Type = "customerRoles", Value = "VIEWER_CUSTOMERROLE2", Properties["http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/attributename"] = "urn:oasis:names:tc:SAML:2.0:attrname-format:uri");

@RuleName = "Send customerRoles VIEWER_CUSTOMERROLE3"
EXISTS([Type == "http://claims.contoso.com/tokenGroups", Value == "EAM-VIEWER-CUSTOMERROLE3"])
 => issue(Type = "customerRoles", Value = "VIEWER_CUSTOMERROLE3", Properties["http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/attributename"] = "urn:oasis:names:tc:SAML:2.0:attrname-format:uri");

📘

Information

For SMP roles, please see SMP user role mapping.