Konfigurationsbeispiele für AAIplus

Work in Progress

Diese Seite ist noch im Aufbau begriffen!
Das Konzept AAIplus sieht u.a. vor, die Entity Category http://aai.dfn.de/category/aai-plus an Service Provider zu vergeben, die ein Datenschutz-Audit absolvieren und im Gegenzug die Zusicherung erhalten, dass die vom jeweiligen SP benötigten Attribute von den teilnehmenden IdPs ohne weitere Rückfragen übertragen werden. Siehe hierzu einstweilen den Beitrag zum Thema in den DFN-Mitteilungen Nr. 96 (ab Seite 13).
Die o.g. Entity Category wird derzeit noch nicht vergeben (Stand Juli 2024). Es sind noch verfahrenstechnische Fragen zu klären.

Die u.g. Beispiele für Attribut-Konfigurationen beziehen sich auf die aktuell gültigen Best Practice Empfehlungen zur Verwendung von Attributen in der DFN-AAI.

Beispiele für die Definition von eduPersonEntitlement und eduPerson(Scoped)Affiliation finden sich unter Attribut-Configuration für Verlagsanbieter, zu schacUserStatus siehe unter User Deprovisionierung, zu eduPersonAssurance siehe REFEDS Assurance Framework - Identity Provider.

/opt/shibboleth-idp/conf/attribute-resolver.xml
    <AttributeDefinition id="uid" xsi:type="PrincipalName" />
 
    <!-- dies hier ist nur eine Auswahl! Bei Bedarf weitere Attribut-Definitionen einfügen -->
 
    <AttributeDefinition id="mail" xsi:type="Simple">
        <InputDataConnector ref="myLDAP" attributeNames="mail"/>
    </AttributeDefinition>
 
    <AttributeDefinition xsi:type="Template" id="displayName">
        <InputDataConnector ref="myLDAP" attributeNames="givenName sn"/>
        <Template>${givenName} ${sn}</Template> 
    </AttributeDefinition>
 
    <AttributeDefinition id="schacHomeOrganization" xsi:type="Simple">
        <InputDataConnector ref="staticAttributes" attributeNames="schacHomeOrganization" />
    </AttributeDefinition>
 
    <AttributeDefinition xsi:type="Simple" id="o">
        <InputDataConnector ref="staticAttributes" attributeNames="o"/>
    </AttributeDefinition>
 
    <!-- Identifier Attributes -->
 
    <AttributeDefinition id="subjectHash" xsi:type="ScriptedAttribute" dependencyOnly="true">
        <InputDataConnector ref="myLDAP" attributeNames="%{idp.persistentId.sourceAttribute}" />
        <Script><![CDATA[
          var digestUtils = Java.type("org.apache.commons.codec.digest.DigestUtils");
          var saltedHash  = digestUtils.sha256Hex(%{idp.persistentId.sourceAttribute}.getValues().get(0) + "%{idp.persistentId.salt}");
          subjectHash.addValue(saltedHash);
        ]]></Script>
    </AttributeDefinition>
 
    <AttributeDefinition xsi:type="Scoped" id="samlSubjectID" scope="%{idp.scope}">
        <InputAttributeDefinition ref="subjectHash" />
    </AttributeDefinition>
 
    <AttributeDefinition xsi:type="Scoped" id="samlPairwiseID" scope="%{idp.scope}">
        <InputDataConnector ref="myStoredId" attributeNames="persistentId"/>
    </AttributeDefinition>
 
    <!-- Deprecated - nur für Kompatibilität mit rückschrittlichen SPs --> 
 
    <!-- gleicher Wert wie für Subject Id -->
    <AttributeDefinition xsi:type="Scoped" id="eduPersonUniqueId" scope="%{idp.scope}">
        <InputAttributeDefinition ref="subjectHash" />
    </AttributeDefinition>
 
    <!-- Targeted ID/Persistent ID -->
    <AttributeDefinition id="eduPersonTargetedID" xsi:type="SAML2NameID" nameIdFormat="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">
        <InputDataConnector ref="myStoredId" attributeNames="persistentId"/>
    </AttributeDefinition>
 
 
    <!-- ========================================== -->
    <!--      Data Connectors                       -->
    <!-- ========================================== -->
 
    <DataConnector id="staticAttributes" xsi:type="Static">
        <Attribute id="schacHomeOrganization">
            <Value>hochschule-example.de</Value>
        </Attribute>
        <Attribute id="schacHomeOrganizationType">
            <Value>urn:schac:homeOrganizationType:eu:higherEducationalInstitution</Value>
        </Attribute>
        <Attribute id="o">
            <Value>Test Organization</Value>
        </Attribute>
    </DataConnector>
 
    <DataConnector id="myStoredId"
        xsi:type="StoredId"
        generatedAttributeID="persistentId"
        encoding="BASE32"
        salt="%{idp.persistentId.salt}">
        <InputAttributeDefinition ref="%{idp.persistentId.sourceAttribute}" />
        <BeanManagedConnection>shibboleth.MySQLDataSource</BeanManagedConnection>
    </DataConnector>
 
    <DataConnector id="myLDAP" xsi:type="LDAPDirectory"
        ldapURL="%{idp.attribute.resolver.LDAP.ldapURL}"
        baseDN="%{idp.attribute.resolver.LDAP.baseDN}" 
        principal="%{idp.attribute.resolver.LDAP.bindDN}"
        principalCredential="%{idp.attribute.resolver.LDAP.bindDNCredential}"
        useStartTLS="%{idp.attribute.resolver.LDAP.useStartTLS:true}"
        connectTimeout="%{idp.attribute.resolver.LDAP.connectTimeout}"
        trustFile="%{idp.attribute.resolver.LDAP.trustCertificates}"
        responseTimeout="%{idp.attribute.resolver.LDAP.responseTimeout}"
        failFastInitialize="%{idp.pool.LDAP.failFastInitialize:false}">
        <FilterTemplate>
            <![CDATA[
                %{idp.attribute.resolver.LDAP.searchFilter}
            ]]>
        </FilterTemplate>
            <ConnectionPool
            minPoolSize="%{idp.pool.LDAP.minSize:3}"
            maxPoolSize="%{idp.pool.LDAP.maxSize:10}"
            blockWaitTime="%{idp.pool.LDAP.blockWaitTime:PT3S}"
            validatePeriodically="%{idp.pool.LDAP.validatePeriodically:true}"
            validateTimerPeriod="%{idp.pool.LDAP.validatePeriod:PT5M}"
            expirationTime="%{idp.pool.LDAP.idleTime:PT10M}" />
    </DataConnector>

Obacht bei Hashfunktion

Existiert bereits eine AttributeDefinition für eduPersonUniqueId, sollte die hierfür verwendete Hashfunktion nachgenutzt werden, da andernfalls Identitätsverlust bei Service Providern droht, die dieses Attribut zur Personalisierung nutzen!

In diesem Fall können Scope und Wert direkt nach samlSubjectID übernommen werden:

/opt/shibboleth-idp/conf/attribute-resolver.xml
    <AttributeDefinition id="samlSubjectID" xsi:type="Prescoped">
        <InputAttributeDefinition ref="eduPersonUniqueId" />
    </AttributeDefinition>

Damit Endnutzer*innen in die Lage versetzt werden können, über das User Consent Modul die Übertragung optionaler Attribute an- oder abzuwählen, muss onlyIfRequired=„false“ gesetzt werden.

Da der Bedarf bzgl. SAML V2.0 Subject Identifier Attribut seitens Relying Parties (SPs) über ein Entity Attribut signalisiert wird, erfolgt die Attributfreigabe über separate Attribute Filter Policies.

/opt/shibboleth-idp/conf/attribute-filter.xml
     <!-- Anonyme Angaben an alle SPs freigeben werden -->
 
     <AttributeFilterPolicy id="ReleaseToAnyone">
        <PolicyRequirementRule xsi:type="ANY" />
 
        <AttributeRule attributeID="eduPersonAssurance" permitAny="true" />
 
        <AttributeRule attributeID="eduPersonEntitlement">
          <PermitValueRule xsi:type="Value" value="urn:mace:dir:entitlement:common-lib-terms"/>
        </AttributeRule>
 
        <AttributeRule attributeID="eduPersonScopedAffiliation">
          <PermitValueRule xsi:type="OR">
              <Rule xsi:type="Value" value="member"          ignoreCase="true" />
              <Rule xsi:type="Value" value="library-walk-in" ignoreCase="true" />
          </PermitValueRule>
         </AttributeRule>
     </AttributeFilterPolicy>
 
 
     <AttributeFilterPolicy id="releaseToAAIplus">
 
       <PolicyRequirementRule 
               xsi:type="EntityAttributeExactMatch"
               attributeName="http://macedir.org/entity-category"
               attributeValue="http://aai.dfn.de/category/aai-plus" />
 
       <AttributeRule attributeID="displayName">
          <PermitValueRule xsi:type="AttributeInMetadata" onlyIfRequired="false"/>
       </AttributeRule>
 
       <AttributeRule attributeID="mail">
          <PermitValueRule xsi:type="AttributeInMetadata" onlyIfRequired="false"/>
       </AttributeRule>
 
       <AttributeRule attributeID="schacHomeOrganization">
         <PermitValueRule xsi:type="AttributeInMetadata" onlyIfRequired="false"/>
       </AttributeRule>       
 
       <AttributeRule attributeID="o">
          <PermitValueRule xsi:type="AttributeInMetadata" onlyIfRequired="false"/>
       </AttributeRule>
 
       <AttributeRule attributeID="schacUserStatus">
         <PermitValueRule xsi:type="AttributeInMetadata" onlyIfRequired="false"/>
       </AttributeRule>
 
       <AttributeRule attributeID="eduPersonScopedAffiliation">
          <PermitValueRule xsi:type="AttributeInMetadata" onlyIfRequired="false"/>
       </AttributeRule>
 
       <AttributeRule attributeID="eduPersonEntitlement">
          <PermitValueRule xsi:type="AttributeInMetadata" onlyIfRequired="false"/>
       </AttributeRule>
 
       <AttributeRule attributeID="eduPersonOrcid">
          <PermitValueRule xsi:type="AttributeInMetadata" onlyIfRequired="false"/>
       </AttributeRule>
 
       <AttributeRule attributeID="eduPersonAssurance">
          <PermitValueRule xsi:type="AttributeInMetadata" onlyIfRequired="false"/>
       </AttributeRule>
 
    </AttributeFilterPolicy>
 
 
    <AttributeFilterPolicy id="releaseSubjectIdToAAIplus">
 
        <PolicyRequirementRule xsi:type="AND"> 
             <Rule xsi:type="EntityAttributeExactMatch"
                   attributeName="urn:oasis:names:tc:SAML:profiles:subject-id:req"
                   attributeValue="subject-id" />
             <Rule xsi:type="EntityAttributeExactMatch"
                   attributeName="http://macedir.org/entity-category"
                   attributeValue="http://aai.dfn.de/category/aai-plus" />
        </PolicyRequirementRule>
 
        <AttributeRule attributeID="samlSubjectID" permitAny="true"/>
    </AttributeFilterPolicy>  
 
 
    <AttributeFilterPolicy id="releasePairwiseIdToAAIplus">
 
        <PolicyRequirementRule xsi:type="AND"> 
             <Rule xsi:type="OR">
                <Rule xsi:type="EntityAttributeExactMatch"
                      attributeName="urn:oasis:names:tc:SAML:profiles:subject-id:req"
                      attributeValue="pairwise-id" />
                <Rule xsi:type="EntityAttributeExactMatch"
                      attributeName="urn:oasis:names:tc:SAML:profiles:subject-id:req"
                      attributeValue="any" />
             </Rule>
             <Rule xsi:type="EntityAttributeExactMatch"
                   attributeName="http://macedir.org/entity-category"
                   attributeValue="http://aai.dfn.de/category/aai-plus" />
        </PolicyRequirementRule>
 
        <AttributeRule attributeID="samlPairwiseID" permitAny="true"/>
    </AttributeFilterPolicy>
/opt/shibboleth-idp/conf/relying-party.xml
    <bean id="shibboleth.UnverifiedRelyingParty" parent="RelyingParty">
        <property name="profileConfigurations">
            <list>
            <!-- hier nix -->
            </list>
        </property>
    </bean>
 
    <!-- für die üblichen AAI-Szenarien reichen die Profile SSO und SLO aus, die transient Id wird für Logout benötigt -->
 
    <bean id="shibboleth.DefaultRelyingParty" parent="RelyingParty">
        <property name="profileConfigurations">
            <list>
                <bean parent="SAML2.SSO" 
                      p:postAuthenticationFlows="#{{'terms-of-use', 'attribute-release'}}"
                      p:nameIDFormatPrecedence="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" />
                <ref bean="SAML2.Logout" />
            </list>
        </property>
    </bean>
 
    <!-- Bestimmte SPs dürfen Attribute Queries durchführen: -->
 
    <bean parent="RelyingPartyByName" 
          c:relyingPartyIds="#{{'https://testsp.aai.dfn.de/shibboleth', 'https://testsp2.aai.dfn.de/shibboleth'}}">
        <property name="profileConfigurations">
            <list>
                <bean parent="SAML2.SSO" 
                      p:postAuthenticationFlows="#{{'terms-of-use', 'attribute-release'}}"
                      p:nameIDFormatPrecedence="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" />
                <ref bean="SAML2.Logout" />
                <ref bean="SAML2.AttributeQuery" />
            </list>
        </property>
    </bean>
  • Zuletzt geändert: vor 5 Monaten