AzureAD mit Authentifizierung am Shibboleth IDP verwenden

Nachdem ein paar Anfragen bei mir gelandet waren, ob man für Office365 auch Shibboleth zur Authentifizierung verwenden kann, hat mir netterweise Michael Simon von SCC des KIT (vielen Dank!!!) deren Erfahrung mitgeteilt und ich geb das auf diesem Wege einfach mal weiter, ohne dass ich alle Details verstehe…

AzureAD unterstützt grundsätzlich SAML 2 kompatible Identity Provider. Durch einige Eigenheiten in der Umsetzung des SAML Standards ist die Anbindung des Shibboleth Identity Provider in der Version >3.4 zwar möglich, aber nicht gerade intuitiv.

Die größte Problematik ist dabei die Interpretation der persistenten NameID. AzureAD erwartet, dass ein Account generiert wird. Die ID des generierten Accounts muss nachher als persistente NameID übermittelt werden. Der Shibboleth IDP generiert diese ID allerdings erst, wenn der Service Provider das erste Mal von einem Benutzer verwendet wird.

Shibboleth-seitig ist es allerdings möglich eine andere ID als persistente NameID zu übertragen. Dazu definieren wir in der global.xml eine Condition, die nur bei dem MicrosoftOnline Service Provider triggert:

<bean id="AzureADCondition" parent="shibboleth.Conditions.RelyingPartyId"
   c:_0="#{{'urn:federation:MicrosoftOnline'}}" />

Diese Condition in der global.xml benötigt einen Neustart des Shibboleth Dienstes. Alle weiteren Änderungen können zur Laufzeit neu geladen werden.

Als nächstes müssen wir in der saml-nameid.xml Änderungen vornehmen, damit die persistente ID nach Standard nicht für den MicrosoftOnline SP generiert wird. Dazu kommentieren wir die Zeile aus, die den PersistentNameID Generator referenziert und ersetzen ihn durch einen eigenen:

<util:list id="shibboleth.SAML2NameIDGenerators">
  <ref bean="shibboleth.SAML2TransientGenerator" />
  <!-- ref bean="shibboleth.SAML2PersistentGenerator" / -->
    <bean parent="shibboleth.SAML2PersistentGenerator">
      <property name="activationCondition">
        <bean parent="shibboleth.Conditions.NOT">
          <constructor-arg>
            <bean parent="shibboleth.Conditions.RelyingPartyId">
              <constructor-arg name="candidates">
                <list>
                  <value>urn:federation:MicrosoftOnline</value>
                </list>
              </constructor-arg>
            </bean>
          </constructor-arg>
        </bean>
      </property>
    </bean>
...

Um die passende ID für MicrosoftOnline zu generieren, benötigen wir einen AttributeSource Generator:

...
		<bean parent="shibboleth.SAML2AttributeSourcedGenerator"
            p:format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
	        p:attributeSourceIds="#{ {'ImmutableID'} }">
		    <property name="activationCondition">
	        	<bean parent="shibboleth.Conditions.RelyingPartyId">
				    <constructor-arg name="candidates">
				        <list>
				            <value>urn:federation:MicrosoftOnline</value>
				        </list>
				    </constructor-arg>
			    </bean>
		    </property>
		</bean>
    
	</util:list>

Wie man sehen kann, benötigen wir für diesen Generator ein passendes Attribut ‚ImmutableID‘ aus dem Attribute Resolver. Dazu kann man im attribute-resolver.xml z. B. folgenden Eintrag vornehmen:

<AttributeDefinition id="ImmutableID" xsi:type="Simple" activationConditionRef="AzureADCondition">
    <InputDataConnector ref="idmConn" attributeNames="eduPersonPrincipalName" />
</AttributeDefinition>

<AttributeDefinition id="IDPEmail" xsi:type="Simple" activationConditionRef="AzureADCondition">
    <InputDataConnector ref="idmConn" attributeNames="mail" />
    <AttributeEncoder xsi:type="SAML2String" name="IDPEmail" friendlyName="IDPEmail" />
</AttributeDefinition>

Dabei kommen diese beiden Attribute bei uns aus dem InputDataConnector „idmConn“. Diese Stellen müssen entsprechend angepasst werden, je nach Setup. Da sich bei uns der „eduPersonPrincipalName“ niemals ändert und eindeutig ist, können wir ihn als gemeinsame ID mit dem AzureAD verwenden.

Das zweite Attribut „IDPEmail“ wird von AzureAD erwartet und sollte die primäre E-Mail Adresse des Benutzers enthalten. Auf alle Fälle, muss sie dem entsprechen, was bei der Erstellung der Benutzer im AzureAD verwendet wird. Das Mapping scheint nicht zu funktionieren, wenn einer der beiden Werte nicht stimmt.

Weitere Konfigurationen sind in der relying-party.xml notwendig, da AzureAD eine signierte Assertion voraussetzt und nicht mit einer signierten SAML Response zufrieden ist. An dieser Stelle sollte man nochmal sicherheitshalber das preferierte NameID Format festlegen. In den Metadaten des MicrosoftOnline SP stehen zwar mehrere zur Auswahl, tatsächlich scheint aber nur die persistente NameID unterstützt zu werden.

    <util:list id="shibboleth.RelyingPartyOverrides">
    
...

        <bean parent="RelyingPartyByName"
              c:relyingPartyIds="#{{ 'urn:federation:MicrosoftOnline' }}">
            <property name="profileConfigurations">
                <list>
                <bean parent="SAML2.SSO"
                        p:encryptAssertions="false"
                        p:signAssertions="true"
                        p:signResponses="false"
	                	p:postAuthenticationFlows="attribute-release" 
                        p:nameIDFormatPrecedence="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" />
                <bean parent="SAML2.ECP"
                        p:encryptAssertions="false"
                        p:signAssertions="true"
                        p:signResponses="false"
                        p:nameIDFormatPrecedence="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" />
                <ref bean="SAML2.Logout" />
                </list>
            </property>
        </bean>		
    </util:list>

Laut Anleitung ist das ECP Profil nur in bestimmten Fällen notwendig. Es wäre also vermutlich möglich, das Profil wegzulassen.

Jetzt fehlen noch die Metadaten des MicrosoftOnline SPs. Diese können durch folgende Konfiguration in der metadata-providers.xml geladen werden:

<MetadataProvider id="ShibbolethMetadata" xsi:type="ChainingMetadataProvider"

...

    <MetadataProvider id="URLMD-MicrosoftAzureAD"
                      xsi:type="FileBackedHTTPMetadataProvider"
                      backingFile="%{idp.home}/metadata/AzureAD-metadata-backingFile.xml"
                      metadataURL="https://nexus.microsoftonline-p.com/federationmetadata/saml20/federationmetadata.xml"
                      maxRefreshDelay="PT2H"> 

		<MetadataFilter xsi:type="EntityRoleWhiteList">
            <RetainedRole>md:SPSSODescriptor</RetainedRole>
        </MetadataFilter>
        
    </MetadataProvider>
    
</MetadataProvider>

Damit der MicrosoftOnline SP das „IDPEmail“ Attribut erhält, wird noch eine Freigabe in der attribute-filter.xml benötigt:

	<AttributeFilterPolicy id="releaseMicrosoftWindowsAzureAD">
        <PolicyRequirementRule xsi:type="Requester" value="urn:federation:MicrosoftOnline" />
               
        <AttributeRule attributeID="IDPEmail">
                <PermitValueRule xsi:type="ANY"/>
        </AttributeRule>
        <AttributeRule attributeID="ImmutableID">
                <PermitValueRule xsi:type="ANY"/>
        </AttributeRule>
	</AttributeFilterPolicy>

Mit diesen Änderungen an der Konfiguration konnten wir z. B. office.com mit AzureAD und Authentifizierung gegen einen Shibboleth Identity Provider verwenden.

Hinterlasse einen Kommentar