SSO with ADFS

📘

Information

Instruction on this page is only valid for the Enterprise Architecture Management (EAM) and Value Stream Management (VSM) products. If you want to implement a single sign-on (SSO) for SaaS Management Product (SMP), please go here.

This site gives best practices how to configure your Active Directory Federation Services (ADFS) when configuring it for SSO with LeanIX.

📘

Attention

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

Setup SSO using Active Directory with ADFS 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 (ADFS) server. ADFS 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 ADFS federation with Shibboleth.

🚧

Attention

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

Usually, the ADFS metadata information can be found at the following URL: https:///FederationMetadata/2007-06/FederationMetadata.xml

Map attributes from Active Directory with ADFS and SAML

When using SAML login with ADFS, 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 https://dev.leanix.net/docs/single-sign-on-sso#section-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 ADFS 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 ADFS federation with LeanIX. Thanks to the support of a very nice LeanIX customer sharing his insights and helping 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");