Skip to content

SAML2 Attribute Queries - Basiskonfiguration der Attribute Query

Warning

This information is preliminary. The documentation will be completed as soon as possible.

In order to deprovision users, Service Providers require the information about a user’s status within the Identity Management System of the Identity Provider.

Identity Provider requirements

  1. The IdP must provide a TargetedId or PairwiseId by creating, storing and releasing it to the Service Provider.
  2. The IdP must support SAML2 Attribute Queries and allow the Service Provider to access user attributes via this endpoint as long as the users exist or the TargetedId or PairwiseId are resolvable. If Service Provider performs the Attribute Query for a non resolvable TargetedId or PairwiseId, the IdP will return an empty result.

Configuring the Shibboleth 4 Identity Provider

attribute-filter.xml

The attribute-filter.xml must be configured in a way which will release all relevant attributes to the Service Provider.

Example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="UTF-8"?>
<AttributeFilterPolicyGroup id="ShibbolethFilterPolicy" <!-- ... -->>

<!-- ... -->

    <!-- MySP -->
    <AttributeFilterPolicy id="MySP">
        <PolicyRequirementRule xsi:type="AND">
            <Rule xsi:type="Requester" value="https://MySP.domain.com"/>
        </PolicyRequirementRule>
        <AttributeRule attributeID="givenName"                    permitAny="true"/>
        <AttributeRule attributeID="sn"                           permitAny="true"/>
        <AttributeRule attributeID="mail"                         permitAny="true"/>
        <AttributeRule attributeID="o"                            permitAny="true"/>
        <AttributeRule attributeID="eduPersonTargetedID"          permitAny="true"/>
        <AttributeRule attributeID="eduPersonPrincipalName"       permitAny="true"/>
        <AttributeRule attributeID="eduPersonAssurance"           permitAny="true"/>
        <AttributeRule attributeID="eduPersonScopedAffiliation"   permitAny="true"/>
    </AttributeFilterPolicy>

<!-- ... -->

</AttributeFilterPolicyGroup>

relying-party.xml

The Attribute Query can be enabled for all Service Providers in relying-party.xml.

Warning

Depending on the Service Providers which are configured in attribute-filter.xml, such a configuration may be a critical data protection breach. We highly recommend to restrict the Attribute Query as described in the following chapter.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?xml version="1.0" encoding="UTF-8"?>
<beans <!-- ... -->>

<!-- ... -->

    <bean id="shibboleth.DefaultRelyingParty" parent="RelyingParty">
        <property name="profileConfigurations">
            <list>
                <bean parent="SAML2.SSO"
                    p:postAuthenticationFlows="#{{'attribute-release'}}"
                    p:nameIDFormatPrecedence="#{{'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'}}"/>

                <!-- ... -->

                <ref bean="SAML2.AttributeQuery" />

                <!-- ... -->

            </list>
        </property>
    </bean>

<!-- ... -->

</beans>

Restricting the Attribute Query to specific Service Providers

The relying-party.xml also allows for restricting the Attribute Query to specific Service Providers.

Info

When using this option, the respective Attribute Query line must be removed from the DefaultRelyingParty bean.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?xml version="1.0" encoding="UTF-8"?>
<beans <!-- ... -->>

<!-- ... -->

<util:list id="shibboleth.RelyingPartyOverrides">
        <bean parent="RelyingPartyByName" c:relyingPartyIds="#{{
          'https://MyIdP1.com',
          'https://MyIdP2.com'}}">
            <property name="profileConfigurations">
                <list>
                    <bean parent="SAML2.SSO"
                      p:postAuthenticationFlows="#{{'attribute-release'}}"
                      p:nameIDFormatPrecedence="#{{'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'}}"/>

                    <!-- ... -->

                    <ref bean="SAML2.AttributeQuery" />

                    <!-- ... -->

                </list>
            </property>
        </bean>
    </util:list>

<!-- ... -->

</beans>

Interpretation of the Attribute Query response by the Service Provider

If a Service Provider receives a non-empty response to an Attribute Query, they may assume for the respective user to exist.

If the response is empty, this may have multiple causes:

  • The user does no longer exist within the Identity Manamgement System of the Identity Provider.

  • The transmitted TransientId/PairwiseId was invalid.

  • The user is no longer in the LDAP-Directory of the Identity Provider, while they may still be present in another, higher level Identity Management System (e.g. a Meta-Directory).

  • The LDAP-connection between Identity Provider Service and LDAP-Directory is inactive.

  • The user has revoked their permission to transmit attributes from the Identity Provider to the Service Provider.

  • The Attribute Query failed for other reasons.

Info

The current best-practice IdP configuration per DFN tutorial will result in revokation of attribute transmission even when the user opens the view of transmitted attributes during the IdP login flow.

The Service Provider is highly advised to implement security measures which prevent immediate deletion of users once they receive an empty Attribute Query result. This may be done via email warning to users or waiting for multiple confirmations of the empty result before performing any actions.

Interpretation of the empty Attribute Query response by the Helmholtz AAI

This section is yet to be completed.

Extended Attribute Query

Reasoning for extension

Identity Providers and Service Providers have reason to extend the minimal configuration which has been described above.

Identity Providers

Protecting user data

Identity Providers should avoid transmitting data of users which are deactivated.

Example

After an employee has left the company, the employer must not transmit any personal information about the employee, even if they are still present in the employer’s Identity Management System.

Deprovisioning of employees following internal offboarding

Each institution may have their own offboarding process and waiting periods before deleting data which has been created by a user. Ideally, external Service Providers should also respect these terms.

Example

A fixed term contract of a scientist expires and is renewed two months later. The user account at the institution will be deactivated and an would only be deleted six months after an employee has left. The scientist will be able to pick up their work when returning after the two months and have access to all their previously owned data.

Service Providers

Information on locked user accounts

In order to ensure secure operation of their service, Service Providers should be informed about locking of users as soon as possible. Depending on the service, it may not be sufficient that users would be unable to authenticate at their home Identity Provider, as services might be accessible via alternative authentication means.

Example

  1. On OpenStack, users authenticate with the service in order to create a virtual machine. Once it has been created, they could log into the virtual machine by only using local accounts via SSH.
  2. Nextcloud provides app-passwords, which act as pseudo accounts and allow direct authentication with the service, e.g. for WebDav or CalDav clients.

Controlling access for deactivated but still existing users

Should an Identity Provider not immediately delete users due to reasons as described in [Deprovisioning of employees following internal offboarding], but rather after a prenegotiated term, Service Providers should be informed about the deactivation before the deletion, so that they may lock users from accessing service ressources in whichever way.

Example

See [Information on locked user accounts]

Compliance with Sirtfi OS4

Service Providers and Identity Providers have the option to comply with Sirtfi OS4 in a technically mature and sufficient way by using extended Attribute Queries.

[OS4] A user’s access rights can be suspended, modified or terminated in a timely manner.

Possible extensions

Disclaimer

Between all of the following extensions of the Attribute Query it will likely not be possible to define a common standard within a Community AAI. This is especially due to heterogenous internal regulations and different Identity Management Systems of the institutions.

schacUserStatus

DFN-Documentation, REFEDS-Documentation

Namespace in Helmholtz AAI

For Helmholtz AAI, the namespace is kept simple:

1
urn:schac:userStatus:de:<centre-domain>:<status>

Example:

1
urn:schac:userStatus:de:helmholtz-berlin.de:active
Stati in Helmholtz AAI

The stati used in Helmholtz AAI are:

1
active

The user exists within the Identity Manamgent System and is able to authenticate via the Identity Provider.

-> The Helmholtz AAI will not perform any action.

1
locked

The user exists within the Identity Manamgent System and locked for a limited term. They cannot authenticate via the Identity Provider.

-> The Helmholtz AAI will also lock the user and inform Service Providers via message broker broadcast to also lock the user, considering alternative authentication meants.

1
deactivated

The user existis within the Identity Management and is deactivated. They cannot authenticate via the Identity Provider and are expected to be deleted after the internal offboarding term is completed.

-> The Helmholtz AAI will lock the user and start it’s deprovisioning process according to the defined offboarding terms.

Configuring schacUserStatus in the Shibboleth 4 Identity Provider

schacUserStatus must be created as a new custom attribute in Shibboleth 4.

If you followed the DFN tutorial for Shibboleth 4, you need to create a new file here:

/opt/shibboleth-idp/conf/attributes/custom/schacUserStatus.properites

1
2
3
4
5
6
7
id=schacUserStatus
transcoder=SAML2StringTranscoder
saml2.name=urn:oid:1.3.6.1.4.1.25178.1.2.19
displayName.de=SchacUserStatus
displayName.en=SchacUserStatus
description.de=Angaben zur Verlässlichkeit einer Identität und ggf. zum aktuellen Login-Vorgang
description.en=Information on the reliability of an identity and, if applicable, the current login process

In order to generate the attribute with it’s values, scripting within attribute-resolver.xml is required.

Depending on the Identity Manamgent System, the stati need to be extracted in different ways.

Info

The following examles are only suggestions, alternate solutions may also be viable.

OpenLDAP

In order to avoid extensions of the LDAP schema for the schacUserStatus, stati may be expressed by using separate OUs for user in a given status:

1
2
3
4
5
ou=users,dc=<domain>,dc=<country-code>
    ou=archive,dc=<domain>,dc=<country-code>
        ou=users,ou=archive,dc=<domain>,dc=<country-code>
            ou=locked,ou=users,ou=archive,dc=<domain>,dc=<country-code>
            ou=disabled,ou=users,ou=archive,dc=<domain>,dc=<country-code>

This will also allow to simply block all users in the OU “archive” from authenticating.

The stati can be extracted as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<!-- ... -->

<!-- schacUserStatus -->
<AttributeDefinition xsi:type="ScriptedAttribute" id="schacUserStatus">
    <InputDataConnector ref="MyLDAP" />
    <Script>
        <![CDATA[
            if (typeof entryDN != "undefined" && entryDN.getValues().size()> 0) {
                var prefix = "urn:schac:userStatus:de:aai.dfn.de:";
                var disabled= "ou=disabled,ou=users,ou=archive,dc=<domain>,dc=<country-code>";
                var locked  = "ou=locked,ou=users,ou=archive,dc=<domain>,dc=<country-code>";

                for (i=0; i<entryDN.getValues().size(); i++) {
                    var tmp = entryDN.getValues().get(i);

                    if (tmp.endsWith(disabled)) {
                        schacUserStatus.addValue(prefix + "idmStatus:disabled");
                    }

                    else if (tmp.endsWith(locked)) {
                        schacUserStatus.addValue(prefix + "idmStatus:locked");
                    }

                    else {
                        schacUserStatus.addValue(prefix + "idmStatus:active");
                    }
                }
            }
        ]]>
    </Script>
</AttributeDefinition>

<!-- ... -->
Active Directory

In Active Directory the attribute UserAccountControl provides the necessary information for active and deactivated. The locked status will require the usage of extension attributes, schema extensions or OUs as described for OpenLDAP.

The stati active and deactivated can be extracted as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<!-- ... -->

<!-- schacUserStatus -->
   <AttributeDefinition id="schacUserStatus" xsi:type="ScriptedAttribute" >
      <InputDataConnector ref="myLDAP" attributeNames="userAccountControl" />
      <Script><![CDATA[
         status=userAccountControl.getValues().get(0);
         returnStatus='urn:schac:userStatus:de:%{idp.scope}:';
         if(status=='512'){
            returnStatus+='active';
         } else {
            returnStatus+='deactivated';
         }
         schacUserStatus.getValues().add(returnStatus);
         ]]>
      </Script>
   </AttributeDefinition>

<!-- ... -->

The other stati will need to be extracted according to the implementation in Active Directory, e.g. as described for OpenLDAP.

Providing schacUserStatus in a GDPR compliant way

This section is yet to be completed.