Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: preserved as v4, pointing to newer guidance


This guidance is for older versions of the IdP. The most recent user contributed guidance can be found here: SAML Proxying EntraID / Azure with the Shibboleth IdP

A French version of this document can be found on the CANARIE website.

Note

Please read and follow the documentation first, before or along with using this example. This documentation is not maintained by the development team and may not be entirely accurate or consistent with the software at any given time. It is a complement to the documentation, not a replacement for it. It is currently out of date with respect to some improvements made in V4.1.


Table of Contents

Overview 

This configuration recipe of the Shibboleth IdP leverages the SAML proxying features such that Azure AD can be used for sign-in while Shibboleth handles the features many R&E federation's trust models value. Using this approach uses just the IdP as a SAML proxy without the necessity of extra elements.

...

Acknowledgements: Thanks to contributors  Former user (Deleted)the Shibboleth team, and others for guidance and input on the material.

IdP Proxying: Appearances and Perspectives

Proxying techniques are confusing at times and it is helpful to understand the approach and your perspective:

...

  • The entity registered in the R&E federation is the Shibboleth IdP, built for and by the R&E community and should meet all technical requirements as does any other Shibboleth IdP
  • Alignment to any federation baseline expectations is not just software but also how it's operated and managed and is in the hands of the IdP operator like any other IdP. 

IdP Proxying: What a Proxy Flow Looks Like

When the user initiates sign-on the following usually happens:

    1. An Authentication request arrives at Shibboleth IdP
    2. The Shibboleth IdP observes it's configured for SAML sign on and redirects to an upstream IdP (Azure AD). Settings for this are controlled in

      1. idp.properties
      2. authn/saml-authn-config.xml 
    3. User Authenticates or has an existing session at upstream IdP (Azure AD)
    4. The upstream IdP (Azure AD) constructs a SAML Assertion with one or more attributes and is sent with the user to the Shibboleth IdP 
    5. The Shibboleth IdP receives the assertion and:
      1. verifies that the assertion arrives from an entity it trusts as configured in metadata-providers.xml

      2. filters the assertion according to rules in attribute-filter.xml
      3. Extracts the real user as configured in attribute-based subject c14n.
        1. Looks through list of AttributesToResolve in the resolver and resolves each one.
        2. Looks through list of resulting attributes in AttributeSourceIds and picks the first valid one to be the principal's name to be used later
      4. Resulting trusted real username is used as $resolutionContext.principal (eg. existing LDAP data connector, etc.) during "standard" attribute resolution process

Implementing the Solution

Prerequisites

Be sure to have these assets in place and appropriate access to them before you start:

  1. A working Shibboleth Identity Provider at V4 or above running somewhere.
  2. An active Azure AD tenant that you have administrative control in
  3. The ability in Azure AD to create an enterprise Non-Gallery SAML App
  4. A suitable attribute available to both IdPs to use as a "joining" attribute used in local lookups if necessary.

Terms and Settings 

This document refers to some key settings and terms described here. For your installation have these on hand to speed up configuration:

  • Your original IdP EntityID: https://idp.example.com/idp
  • Your Upstream IdP EntityID which is Azure AD Identifier: https://sts.windows.net/<sts_tenant_id>/
    • sts_tenant_id can be found most easily by creating a relying parting in Azure AD to work with:
      • sign into the Azure AD Portal -> choose Enterprise Applications -> Create New Application  > Non Gallery Application → Actually create one → select SAML Sign On  - > select SAML Sign  On settings
      • Section 4 contains  the Azure AD Identifier which includes the trailing slash
  • The Proxy Joining attribute common to both services:
    • SamAccountName is often a good choice and appears as 'name' in claims.
      • will exist as a 'scoped' username
      • the scope being that of the domain used on-premises and is usually internet friendly (not something.local or something.int)
  • Relying Party/Service Provider Microsoft will use "Relying Party" at times to mean "Service Provider"

Steps and Tasks

Step 1. Configuring Trust Between Azure AD and the Shibboleth IdP

There are 3 main trust-related configurations to adjust:

...

3. the Azure AD trust to the Shibboleth IdP as a Relying Party

Trust Task: 1. Update your IdP's metadata

As your IdP will need act as an SP, you'll need extra blocks in your entity's metadata.

...

Code Block
languagexml
collapsetrue
<EntityDescriptor entityID="https://idp.example.com/idp" ...>

    <!-- Already present IdP data -->
    <IDPSSODescriptor ...>
        ...
    </IDPSSODescriptor>

    <AttributeAuthorityDescriptor>
        ...
    </AttributeAuthorityDescriptor>


    <!-- New SP block -->
    <SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">

        <KeyDescriptor use="signing">
            <ds:KeyInfo>
                <ds:X509Data>
                    <ds:X509Certificate>
                    ...Signing Certificate from IdP...
                    </ds:X509Certificate>
                </ds:X509Data>
            </ds:KeyInfo>
        </KeyDescriptor>
        <KeyDescriptor use="encryption">
            <ds:KeyInfo>
                <ds:X509Data>
                    <ds:X509Certificate>
                    ...Encryption Certificate from IdP...
                    </ds:X509Certificate>
                </ds:X509Data>
            </ds:KeyInfo>
        </KeyDescriptor>

    <AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://idp.example.com/idp/profile/Authn/SAML2/POST/SSO" index="0"/>
</SPSSODescriptor>

</EntityDescriptor>

Trust Task: 2. Register your IdP with Azure AD

An Azure AD Enterprise Application needs to be created of type 'Non-Gallery Application' and configured for SAML.

...

Keep this Relying Party editing environment open for the next step.

Trust Task: 3. Register the upstream IdP's metadata locally

Your Shibboleth IdP doesn't know of the Azure AD IdP so you need to register it locally. This is handled just like any other metadata and can be included in your metadata-providers.xml as a new <MetadataProvider> element. For example:

...

Note

Note!

  • About certificates:
    • The certificate generated by Azure AD is only 3 years in duration and is the trust between Azure and the Shibboleth Proxy only.
    • Expect Azure AD to cease trust when it expires.
    • Also expect certificate rollover between Azure AD and your IdP instance to be handled by the IdP admin team. 
  • About the metadata download  itself:
    • There are no linefeeds between lines (so reformat e.g. with xmllint as shown above, if desired)
    • It contains unnecessary elements that can be removed to reduce the size of the file:
      • a signature embedded in the top of the file
      • The section Fed:ClaimTypesOffered 

Trust Task: 4. Configure Azure AD Attribute Release to the Shibboleth IdP

While still in the edit mode of the Relying Party, configure the necessary attributes needed for the Shibboleth IdP operation.

...

Info

user.userprincipalname is the usual choice for the main user identifier but review your practices carefully around its use and potential re-use. This is going to be especially critical around MFA and assurance attestations to ensure they have a unique identifier that is unchanging.

Step 2. Configure the IdP for Proxing Behaviour

The following changes are needed to adjust the IdP to proxying behaviour:

  1. Changing the authentication flow to SAML authentication
  2. Configuring which Entity to delegate to for the flow
  3. Update attribute filter to allow incoming attributes to be ingested
  4. Set up attribute extraction through Subject Canonicalisation (c14n and resolver)

Proxy Task 1. Change the IdP authentication flow to SAML

There are three steps for this task:

...

2. Enable the flow by updating idp.authn.flows in idp.properties to set it to SAML:

idp.authn.flows=SAML

Proxy Task 2. Update Your Attribute Filter

The IdP will not ingest attributes from the Azure AD Upstream IdP unless they're allowed in by a filter.

...

Code Block
languagexml
<AttributeFilterPolicy id="FilterPolicyObject-Proxy-FromAzure-byIssuer-Type">
    <PolicyRequirementRule xsi:type="Issuer" value="https://sts.windows.net/<sts_tenant_id>/" />
         
    <AttributeRule attributeID="azureDisplayname" permitAny="true" />
    <AttributeRule attributeID="azureGivenname" permitAny="true" />
    <AttributeRule attributeID="azureSurname" permitAny="true" />
    <AttributeRule attributeID="azureAuthnmethodsreferences" permitAny="true" />
    <AttributeRule attributeID="azureIdentityprovider" permitAny="true" />
    <AttributeRule attributeID="azureTenantid" permitAny="true" />
    <AttributeRule attributeID="azureEmailaddress" permitAny="true" />
    <AttributeRule attributeID="azureObjectidentifier" permitAny="true" />
    <AttributeRule attributeID="azureName">
        <PermitValueRule xsi:type="ScopeMatchesShibMDScope" />
    </AttributeRule>
</AttributeFilterPolicy>

Proxy Task 3. Enable IdP to Recognize Azure AD Claims 

Azure AD issues SAML assertions, however they are presented in an Azure/WS-Fed-centric naming convention (as "claims").

...

Now that we have the the IdP able to interpret claims from Azure AD, we need to turn our attention to using them for user canonicalization and for populating our attributes.

Proxy Task 4. Subject Canonicalisation

This workflow takes the incoming assertion and extracts some data from it to work out the canonical (authoritative/normalized) username of the user logging in from Azure.

...

$resolutionContext.principal

Proxy Task 5. Configuring Attribute pass-through and/or hybrid resolving

Attributes originating from Azure AD are referenced in attribute-resolver.xml like this:

...

Code Block
languagexml
<AttributeDefinition xsi:type="SubjectDerivedAttribute"
    forCanonicalization="false"
    id="mail"
    principalAttributeName="azureEmailaddress" />

<AttributeDefinition xsi:type="SubjectDerivedAttribute"
    forCanonicalization="false"
    id="displayName"
    principalAttributeName="azureDisplayname" />

<AttributeDefinition xsi:type="SubjectDerivedAttribute"
    id="eduPersonPrincipalName"
    principalAttributeName="azureName" />

Proxy Task 6. Handling REFEDS AuthnContext Requests (optional)

Azure does not currently have a documented way to influence the behavior of the AuthnContext in their SAML assertions.  However, Shibboleth provides the means to translate proxy requests and responses via authn/authn-comparison.xml. The example below handles REFEDS MFA requests:

Code Block
languagexml
<util:map id="shibboleth.PrincipalProxyRequestMappings">
	<entry>
		 <key>
			<bean parent="shibboleth.SAML2AuthnContextClassRef"
                  c:classRef="https://refeds.org/profile/mfa" />
		</key>
		<list>
			<bean parent="shibboleth.SAML2AuthnContextClassRef"
                  c:classRef="http://schemas.microsoft.com/claims/multipleauthn" />
		</list>
	</entry>
</util:map>
<util:map id="shibboleth.PrincipalProxyResponseMappings">
	<entry>
		 <key>
			<bean parent="shibboleth.SAML2AuthnContextClassRef"
                          c:classRef="http://schemas.microsoft.com/claims/multipleauthn" />
		</key>
		<list>
			<bean parent="shibboleth.SAML2AuthnContextClassRef"
                          c:classRef="https://refeds.org/profile/mfa" />
		</list>
	</entry>
</util:map>

Update the support matrix for the SAML authentication flow to understand the REFEDS MFA profile

(for v4.0.1) Update the authn/SAML bean in authn/general-authn.xml so it understands the REFEDS MFA profile by adding a supportedPrincipals property:

...

Changes required in v4.1 may be different and you should look at the authn.properties file. More details here: SAMLAuthnConfiguration

Testing

Restart your IdP for your changes to take effect.  Because this is a SAML proxy configuration it doesn't make sense to use  aacli since it won't have the required information available to it.

Some sites have a developer account which has a tenant that can test entirely isolated from the production tenant. Alternatively you can create a different Azure AD non-gallery SAML app per IdP – one for production, one for pre-production etc. There's no hard and fast rule on the best way however the developer route is free and provides a great model for isolation between credentials as it's a different cookie domain entirely.

Related content / Recommended Reading

...