Persistent NameID

context

Some SP and vendors wants a particular nameID to authorize acces to their services, ei eduPersonTargetedID as a persistentID . My objective is to be able to send this particular nameID only to specific SPs while still take advantage of a default nameid-format:transient for the other majority of SPs , so that I have no need to manage a SGBD to store persistent ID ( ei eduPersonTargeted ) in a DB .

reference :

nameID

saml-nameid.properties

configure saml-nameid.properties to set the source attribute of a computed persistent ID

[root@idp3 conf]# cat saml-nameid.properties
# Properties involving SAML NameIdentifier/NameID generation/consumption
# Persistent IDs can be computed on the fly with a hash, or managed in a database

# For computed IDs, set a source attribute and a secret salt:
idp.persistentId.sourceAttribute = eduPersonPrincipalName
idp.persistentId.useUnfilteredAttributes = true
# Do *NOT* share the salt with other people, it's like divulging your private key.
idp.persistentId.algorithm = SHA
idp.persistentId.salt = secretpasslongenough
# To use a database, use shibboleth.StoredPersistentIdGenerator
idp.persistentId.generator = shibboleth.ComputedPersistentIdGenerator

if it fails, setting idp.service.failFast = true in services.properties force IDP to fail start and showed me a fail on IDP startup with :

Caused by: net.shibboleth.utilities.java.support.component.ComponentInitializationException: Service 'shibboleth.NameIdentifierGenerationService': could not perform initial load
ry.BeanCreationException: Error creating bean with name 'shibboleth.ComputedPersistentIdGenerator' defined in file [/opt/shibboleth-idp/system/conf/saml-nameid-system.xml]: Invocation of init method failed; nested exception is net.shibboleth.utilities.java.support.component.ComponentInitializationException: 
Salt must be at least 16 bytes in size

the idp.persistentId.salt must be long enough !

then we need to uncommented <ref bean=“shibboleth.SAML2PersistentGenerator” /> in saml-nameid.xml expecting to get a Persitent nameID format for the targeted SP “https://services.renater.fr/shibboleth

idp v4

quite the same as in V3 , except here we choose mail attribute and validate advice to use BASE32 encoding

[root@idp4 conf]# vim saml-nameid.properties
idp.persistentId.algorithm = SHA
idp.persistentId.salt = secretpasslongenough16bytes
idp.persistentId.sourceAttribute = mail
idp.persistentId.useUnfilteredAttributes = true
idp.persistentId.encoding = BASE32

idp.persistentId.generator = shibboleth.ComputedPersistentIdGenerator

saml-nameid.xml

but finally , there's no need to get into CustomNameIDGenerationConfiguration : https://wiki.shibboleth.net/confluence/display/IDP30/CustomNameIDGenerationConfiguration

nor list SPs in activationCondition

https://wiki.shibboleth.net/confluence/display/IDP30/ActivationConditions (c:candidates="#{{'https://sp.example.com/shibboleth', 'https://another.example.com/shibboleth'}}" />

below bean parent=“shibboleth.SAML2AttributeSourcedGenerator” is commented

<!-- SAML 2 NameID Generation -->
    <util:list id="shibboleth.SAML2NameIDGenerators">
        <ref bean="shibboleth.SAML2TransientGenerator" />
        <!-- Uncommenting this bean requires configuration in saml-nameid.properties. -->
        <ref bean="shibboleth.SAML2PersistentGenerator" />
        <!--
        <bean parent="shibboleth.SAML2AttributeSourcedGenerator"
            p:format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
            p:attributeSourceIds="#{ {'mail'} }" >
                <property name="activationCondition">
                <bean parent="shibboleth.Conditions.RelyingPartyId" c:candidate="https://services.renater.fr/shibboleth" />
                </property>
        </bean>
        -->

    </util:list>

if federation metadata ask explicitly for the correct nameIDs as is the case with entityID=“https://monitor.eduroam.org/sp/module.php/saml/sp/metadata.php/default-sp

cf metadata below

idp v4

uncomment bean=“shibboleth.SAML2PersistentGenerator”

[root@idp4 conf]# vim saml-nameid.xml

<!-- SAML 2 NameID Generation -->
    <util:list id="shibboleth.SAML2NameIDGenerators">

        <ref bean="shibboleth.SAML2TransientGenerator" />

        <!-- Uncommenting this bean requires configuration in saml-nameid.properties. -->
        <ref bean="shibboleth.SAML2PersistentGenerator" />

metada requesting persistendID

example

md:EntityDescriptor entityID="https://monitor.eduroam.org/sp/module.php/saml/sp/metadata.php/default-sp">
    <md:Extensions>
      <mdattr:EntityAttributes>
        <saml:Attribute Name="http://macedir.org/entity-category" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">

<md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</md:NameIDFormat>
      <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>

<md:RequestedAttribute Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/>

because NameIDFormat in edugain metadata above, lists persitent before transient then , no matter the order beans are defined in saml-nameid.xml (here transient before persistent)

 <util:list id="shibboleth.SAML2NameIDGenerators">
        <ref bean="shibboleth.SAML2TransientGenerator" />
  <ref bean="shibboleth.SAML2PersistentGenerator" />
        <bean parent="shibboleth.SAML2AttributeSourcedGenerator"

that's the order in metadata that will decide which one to use .

Note also that the SP in question supports the eduPersonTargetedID attribute,

<md:RequestedAttribute Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/>

oid 1.3.6.1.4.1.5923.1.1.1.10 stands for : eduPersonTargetedID ! (cf https://www.internet2.edu/products-services/trust-identity/mace-registries/internet2-object-identifier-oid-registrations/)

attribute eduPersonTargetedID

The NameID generation is separate from the attribute resolution. Now that we have the NameID working, we can generate the eduPersonTargetedID by modifying attribute-resolver-ldap.xml (attribute-resolver.xml). Here is my configuration:

        <resolver:DataConnector xsi:type="dc:ComputedId"
                          id="computedID"
                          generatedAttributeID="computedID"
                          sourceAttributeID="%{idp.persistentId.sourceAttribute}"
                          salt="%{idp.persistentId.salt}">
      <resolver:Dependency ref="myLDAP" />
  </resolver:DataConnector>

  <resolver:AttributeDefinition xsi:type="ad:SAML2NameID" id="eduPersonTargetedID"
                                nameIdFormat="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" sourceAttributeID="computedID">
      <resolver:Dependency ref="computedID" />
      <resolver:AttributeEncoder xsi:type="enc:SAML1XMLObject" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" />
      <resolver:AttributeEncoder xsi:type="enc:SAML2XMLObject" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" friendlyName="eduPersonTargetedID" />
  </resolver:AttributeDefinition>

resolver idp 4

xml syntaxe changes sligthly :

[root@idp4 conf]# vim attribute-resolver-ldap.xml 

<!--  jeh edupersonTargetedID eduroam monitor -->
     <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>
  
 <!--  jeh edupersonTargetedID eduroam monitor -->
    <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>

test / validate with aacli

aacli.sh is a script that allows us to test locally what the IDP with send as nameIDs and attributes for a specific SP and associated principal (login) . we tes here our persistendID requested by SP and eduPersonTargetedID required :

[root@idp3 shibboleth-idp]# ./bin/aacli.sh --requester=https://monitor.eduroam.org/sp/module.php/saml/sp/metadata.php/default-sp --configDir=conf/ --principal=procaccia --saml2

2017-12-19 13:38:33,906 - DEBUG [org.opensaml.saml.saml2.profile.impl.EncryptAssertions:132] - Profile Action EncryptAssertions: Assertion before encryption:
<?xml version="1.0" encoding="UTF-8"?>
<saml2:Assertion ID="_f4d649d8cada1f44d2efa5ff53ff3324"
    IssueInstant="2017-12-19T12:38:33.763Z" Version="2.0" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
    <saml2:Issuer>https://idp3.tem-tsp.eu/idp/shibboleth</saml2:Issuer>
    <saml2:Subject>
        <saml2:NameID
            Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
            NameQualifier="https://idp3.tem-tsp.eu/idp/shibboleth" SPNameQualifier="https://monitor.eduroam.org/sp/module.php/saml/sp/metadata.php/default-sp">cypRgyH6cq0Iifq1UFZGlgCKLDB=</saml2:NameID>
        <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
            <saml2:SubjectConfirmationData Address="191.160.129.124"
                InResponseTo="_652d7ff66093e86dc79aa45711b99f7dfdcf7a2501"
                NotOnOrAfter="2017-12-19T12:43:33.835Z" Recipient="https://monitor.eduroam.org/sp/module.php/saml/sp/saml2-acs.php/default-sp"/>
        </saml2:SubjectConfirmation>
    </saml2:Subject>
    <saml2:Conditions NotBefore="2017-12-19T12:38:33.763Z" NotOnOrAfter="2017-12-19T12:43:33.763Z">
        <saml2:AudienceRestriction>
            <saml2:Audience>https://monitor.eduroam.org/sp/module.php/saml/sp/metadata.php/default-sp</saml2:Audience>
        </saml2:AudienceRestriction>
    </saml2:Conditions>
    <saml2:AuthnStatement AuthnInstant="2017-12-19T12:38:27.135Z" SessionIndex="_26a4eacab6d659a933907f74b73cf807">
        <saml2:SubjectLocality Address="191.160.129.124"/>
        <saml2:AuthnContext>
            <saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml2:AuthnContextClassRef>
        </saml2:AuthnContext>
    </saml2:AuthnStatement>
    <saml2:AttributeStatement>
        <saml2:Attribute FriendlyName="uid"
            Name="urn:oid:0.9.2342.19200300.100.1.1" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
            <saml2:AttributeValue
                xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string">procaccia</saml2:AttributeValue>
        </saml2:Attribute>
        <saml2:Attribute FriendlyName="mail"
            Name="urn:oid:0.9.2342.19200300.100.1.3" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
            <saml2:AttributeValue
                xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string">jehan.procaccia@tem-tsp.eu</saml2:AttributeValue>
        </saml2:Attribute>
        <saml2:Attribute FriendlyName="eduPersonTargetedID"
            Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
            <saml2:AttributeValue>
                <saml2:NameID
                    Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
                    NameQualifier="https://idp3.tem-tsp.eu/idp/shibboleth" SPNameQualifier="https://monitor.eduroam.org/sp/module.php/saml/sp/metadata.php/default-sp">cypRgyH6cq0Iifq1UFZGlgCKLDB=</saml2:NameID>
            </saml2:AttributeValue>
        </saml2:Attribute>
        <saml2:Attribute FriendlyName="eduPersonPrincipalName"
            Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.6" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
            <saml2:AttributeValue
                xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string">procaccia@tem-tsp.eu</saml2:AttributeValue>
        </saml2:Attribute>
    </saml2:AttributeStatement>
</saml2:Assertion>

2017-12-19 13:38:34,036 - INFO [Shibboleth-Audit.SSO:241] - 20171219T123834Z|urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST|_652d7ff66093e86dc79aa45711b99f7dfdcf7a2501|https://monitor.eduroam.org/sp/module.php/saml/sp/metadata.php/default-sp|http://shibboleth.net/ns/profiles/saml2/sso/browser|https://idp3.tem-tsp.eu/idp/shibboleth|urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST|_e20f43530af84efaaf7f001d4ecc0f6f|procaccia|urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport|

uid,mail,eduPersonTargetedID,eduPersonPrincipalName|cypRgyH6cq0Iifq1UFZGlgCKLDA=|_f4d649d8cada1f44d2efa5ff53ff3324|

aacli idp v4

[root@idp4 shibboleth-idp]# ./bin/aacli.sh --requester=https://monitor.eduroam.org/sp/module.php/saml/sp/metadata.php/default-sp --configDir=conf/ --principal=proc

{
"requester": "https://monitor.eduroam.org/sp/module.php/saml/sp/metadata.php/default-sp",
"principal": "proc",
"attributes": [
  {
    "name": "eduPersonTargetedID",
    "values": [
        "RJRXNKY474MMFO27SECRE3DKNTPAKY5V"
    ]
  },
  {
    "name": "displayName",
    "values": [
        "Jeh PROC"
    ]
  },
  {
    "name": "mail",
    "values": [
        "jeh.proc@em-tsp.eu"
    ]
  }
]
}

idp v4 logs

2022-05-02 22:50:53,593 - 157.159.10.9 - INFO [Shibboleth-Audit.SSO:283] - 157.159.10.9|2022-05-02T20:50:25.379162Z|2022-05-02T20:50:53.593227Z|procac|https://monitor.eduroam.org/sp/module.php/saml/sp/metadata.php/default-sp|_5265b1224215d57621ebc3dd7e2263a5|password|2022-05-02T20:50:41.088993Z|mail,eduPersonTargetedID,displayName|AAdzZWNyZXQxfd6FaL2H/oTzHRhzrhRYxB4SV1aFGDPXSKgf8zyheoU7yyMyorGzsRIiss4rp0v/kQTJARgY693ws9C2ZVVfJ1AguusrwvXlzIDKsXNispCRrjWnL7UOuyXxgfPo1I9EopKzRRcf0HI2RXd9cRI7UQIuuI1ufkrTMS/TzuuSEZzd96bfeUA=|transient|false|true|AES128-CBC|Redirect|POST||Success||d2c06d37c962ed62666b31a6791aaf0a1b27467c8719dcbb865de58ed67b78f5|Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.3