Attribute release configuration

The IdP releases SAML attributes to SPs to provide information about the organisation and user that the IdP represents for a given authentication. Some are privacy-preserving and some are not, so your organisation needs to give consideration to which attributes are released to which SPs. For the UK federation's attribute release recommendations generally, please see section 7 of the UK federation's Technical Recommendations for Participants. There are four attributes that the UK federation regards as "core" attributes: eduPersonScopedAffiliation, eduPersonTargetedID, eduPersonPrincipalName and eduPersonEntitlement. The most commonly used of these are eduPersonScopedAffiliation and eduPersonTargetedID, so we focus on those here.

Each attribute must have a definition in the attribute-resolver.xml file, which gives instructions for generating the attribute value and format; and a filter in the attribute-filter.xml file, which gives instructions on which SPs it can be released to and under which circumstances.

Attribute resolver configuration

Details of the Shibboleth IdP attribute resolver configuration are given in the Shibboleth attribute resolver configuration documentation. The attribute resolver configuration specifies how attributes are retrieved or generated on behalf of your users; the conf/attribute-resolver.xml file is used for this.

Many organisations will be using Active Directory/LDAP for authentication and attribute retrieval, so we focus on that here. Some simple attribute definitions follow, with an example LDAP connector and ComputedId connector. These are based on examples in the file %{idp.home}/conf/examples/attribute-resolver-ldap.xml. Your attribute definitions will depend on which attributes are available in your LDAP.

Copy the file %{idp.home}/conf/examples/attribute-resolver-ldap.xml to %{idp.home}/conf/attribute-resolver.xml and use that as a starting point. You will need to make some changes according to your organisation's local set-up.

 <AttributeResolver
        xmlns="urn:mace:shibboleth:2.0:resolver"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver
        http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd">

     <AttributeDefinition xsi:type="Scoped" id="eduPersonPrincipalName" scope="%{idp.scope}">
         <InputDataConnector ref="myLDAP" attributeNames="sAMAccountName"/>
     </AttributeDefinition>

     <AttributeDefinition xsi:type="Scoped" id="eduPersonScopedAffiliation" scope="%{idp.scope}">
         <InputDataConnector ref="myLDAP" attributeNames="eduPersonAffiliation"/>
     </AttributeDefinition>

     <AttributeDefinition xsi:type="Scoped" id="samlPairwiseID" scope="%{idp.scope}">
         <InputDataConnector ref="computed" attributeNames="computedId"/>
     </AttributeDefinition>

     <!-- Deprecated eduPersonTargetedID attribute -->

     <AttributeDefinition xsi:type="SAML2NameID" id="eduPersonTargetedID"
         nameIdFormat="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">
         <InputDataConnector ref="computed" attributeNames="computedId"/>
         <AttributeEncoder xsi:type="SAML1XMLObject" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10"/>
         <AttributeEncoder xsi:type="SAML2XMLObject" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10"
                           friendlyName="eduPersonTargetedID"/>
     </AttributeDefinition>

     <!-- Example LDAP DataConnector based on conf/examples/attribute-resolver-ldap.xml -->

     <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}"
         connectionStrategy="%{idp.attribute.resolver.LDAP.connectionStrategy}"
         noResultIsError="true"
         multipleResultsIsError="true"
         excludeResolutionPhases="c14n/attribute"
         exportAttributes="sAMAccountName eduPersonAffiliation">
         <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}"
             validateDN="%{idp.pool.LDAP.validateDN:}"
             validateFilter="%{idp.pool.LDAP.validateFilter:(objectClass=*)}"
             expirationTime="%{idp.pool.LDAP.idleTime:PT10M}"/>
     </DataConnector>

     <!--
     DataConnector for pairwise-id (example depends in part on saml-nameid.properties).
     Note that this relies on BASE32 encoding in accordance with the attribute definition.
     Older uses of this plugin for legacy eduPersonTargetedID/NameID values may require
     different settings.
     -->

     <DataConnector id="computed" xsi:type="ComputedId"
             excludeResolutionPhases="c14n/attribute"
             generatedAttributeID="computedId"
             salt="%{idp.persistentId.salt}"
             algorithm="%{idp.persistentId.algorithm:SHA}"
             encoding="BASE32">
         <InputDataConnector ref="myLDAP" attributeNames="%{idp.persistentId.sourceAttribute}" />
     </DataConnector>

 </AttributeResolver>

The example above gives attribute definitions for the SAML attributes eduPersonPrincipalName eduPersonScopedAffiliation, samlPairwiseID, and eduPersonTargetedID. The attribute definitions depend on the DataConnector with id="myLDAP". If your LDAP connection is secured with SSL or StartTLS then you should not need to make any changes; if it is not secured then you may need to remove or comment out the following lines from the myLDAP DataConnector:

 useStartTLS="%{idp.attribute.resolver.LDAP.useStartTLS:true}"
 trustFile="%{idp.attribute.resolver.LDAP.trustCertificates}"

We strongly recommend you configure your LDAP Server to support either StartTLS or SSL/TLS LDAP over SSL/TLS with a Certificate, and re-configure your Shibboleth IdP accordingly.

You will probably need to make changes to the following line:

 exportAttributes="sAMAccountName eduPersonAffiliation">

In our example, the sAMAccountName and eduPersonAffiliation directory attributes are retrieved from the LDAP directory to be used as the basis for building your SAML attributes. You may need to change these, and/or add others to the list, depending on which attributes are stored in your LDAP directory and what your SAML attribute requirements are. sAMAccountName (the username of the authenticating user) is used in this example as a source attribute for the SAML attribute eduPersonPrincipalName. eduPersonAffiliation, a multi-valued directory attribute containing one or more user affiliations, such as (staff, member) or (student, member), is used in this example as a source attribute for the SAML attribute eduPersonScopedAffiliation.

eduPersonScopedAffiliation

Assuming you have a DataConnector configuration with id="myLDAP", and the LDAP has been populated with the eduPersonAffiliation attribute for all your users, then you can use the eduPersonAffiliation attribute as the basis to generate eduPersonScopedAffiliation with the following snippet in attribute-resolver.xml:

 <AttributeDefinition xsi:type="Scoped" id="eduPersonScopedAffiliation" scope="%{idp.scope}">
     <InputDataConnector ref="myLDAP" attributeNames="eduPersonAffiliation"/>
 </AttributeDefinition>

If the LDAP has not been populated with eduPersonAffiliation and it is not possible to arrange for it to be populated then you may need to use an alternative attribute definition for eduPersonAffiliation, based on other attributes or groups in the LDAP directory.

eduPersonTargetedID

This attribute again depends on having a DataConnector configuration to connect to your LDAP. It also requires a ComputedId DataConnector. See the DataConnector with id="computed" in the example above.

You should not need to make any changes to that; but you will need to make some changes to the file saml-nameid.properties. In saml-nameid.properties, set the idp.persistentId.sourceAttribute be the name of a directory attribute suitable for use as a source attribute for eduPersonTargetedID and other persistent SAML attributes. Whichever source attribute is chosen, it should not change over time. Commonly the username is used; in OpenLDAP this is often called uid.

 idp.persistentId.sourceAttribute=uid

In Active Directory, the username is often called sAMAccountName, although this has been known to change during the lifetime of a user's account. Depending on your system, either objectGUID or objectSid could be used.

The objectGUID is binary, so if it is to be used as the source attribute it should be declared as binary by adding this line to the LDAP DataConnector with id="myLDAP":

 <LDAPProperty name="java.naming.ldap.attributes.binary" value="objectGUID"/>

If you use objectSid, you'll need to add a similar element to the LDAP DataConnector.

You also need to set the property idp.persistentId.salt in %{idp.home}/credentials/secrets.properties. It is a random string of at least 16 bytes which you choose. It should be kept secret.

 idp.persistentId.salt=0123456789abcdef

Important: if you are migrating from an earlier deployment you should use the same source attribute and salt value as you used previously, and set idp.persistentId.encoding = BASE64 in saml-nameid.properties, to ensure that the same values are generated for each of your users as were previously. This is necessary to retain access to personalisations saved on SPs that are keyed to eduPersonTargetedID values.

 idp.persistentId.encoding = BASE64

And here then is the configuration snippet in attribute-resolver.xml for eduPersonTargetedID:

 <AttributeDefinition xsi:type="SAML2NameID" id="eduPersonTargetedID"
     nameIdFormat="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">
     <InputDataConnector ref="computed" attributeNames="computedId"/>
     <AttributeEncoder xsi:type="SAML1XMLObject" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10"/>
     <AttributeEncoder xsi:type="SAML2XMLObject" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10"
                       friendlyName="eduPersonTargetedID"/>
 </AttributeDefinition>

Attribute filter configuration

Details of the Shibboleth IdP attribute filter configuration are given in the Shibboleth attribute filter configuration documentation. The attribute filter configuration determines which attributes are released to which service providers, and is configured in the conf/attribute-filter.xml file. Most service providers in the UK federation require the attribute eduPersonScopedAffiliation with an affiliation value equivalent to full membership, eg. member, staff or student. The affiliation values released for a given user must be determined on the basis of the user's genuine affiliation with your organisation from your organisation's point of view.

In general the UK federation considers there to be very little personally identifying information carried by either eduPersonScopedAffiliation or eduPersonTargetedID so considers it safe to release them to any SP; the following configuration snippet does just that. However, your organisation should do its own risk analysis in consultation with its data protection officer rather than taking our word for it.

Note that this snippet would release these two attributes to any SP with which the IdP successfully authenticated; this might be a UK federation SP, or an SP imported from another federation via eduGAIN interfederation, or another SP for which the IdP has the metadata configured one way or another. More sophisticated attribute filters are possible; please see the Shibboleth documentation.

This simple example releases to any SP.

 <AttributeFilterPolicyGroup id="ShibbolethFilterPolicy"
        xmlns="urn:mace:shibboleth:2.0:afp"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="urn:mace:shibboleth:2.0:afp
        http://shibboleth.net/schema/idp/shibboleth-afp.xsd">

    <!-- Release eduPersonScopedAffiliation and eduPersonTargetedID attributes to any SP. -->
    <AttributeFilterPolicy id="releaseToAnyone">
        <PolicyRequirementRule xsi:type="ANY" />
        <AttributeRule attributeID="eduPersonScopedAffiliation" permitAny="true" />
        <AttributeRule attributeID="eduPersonTargetedID" permitAny="true" />
    </AttributeFilterPolicy>

 </AttributeFilterPolicyGroup>