I recently tried to clone an existing SSO-protected application to use a new IdP. The older instance was protected using SAML (keycloak based) and worked fine. Now the IdP changed to (a much larger) SimpleSAMLphp and while the login itself worked the application refused to work.
Suspected culprit: attributes (missing, unmapped or mapped the wrong way?)
So here’s what I did to find the cause of the problems.
IdP Transmitted attributes
While testing it is nice to get a consent information displayed. This (optional) feature allows you to keep track of the attributes transmitted from your IdP to the SP.
However the output of the IdP’s consent page (at least in my case) does not give and further hints about the internally used formats (OIDs):
eduPersonPrincipalName | marcel@anotherdomain.de |
displayName | Marcel XYZ |
marcel@anotherdomain.de | |
eduPersonAssurance | https://refeds.org/assurance https://refeds.org/assurance/ID/unique https://refeds.org/assurance/ID/eppn-unique-no-reassign https://refeds.org/assurance/IAP/local-enterprise https://refeds.org/assurance/IAP/low https://refeds.org/assurance/IAP/medium https://refeds.org/assurance/ATP/ePA-1m https://refeds.org/assurance/ATP/ePA-1d https://refeds.org/assurance/profile/cappuccino |
Shibboleth SP received attributes
So next step is to check what attributes were received on the SP side. When using Shibboleth here, we can just check the session information available under /Shibboleth.sso/Session on the SP site:
Miscellaneous
Session Expiration (barring inactivity): 479 minute(s)
Client Address: 123.123.123.123
SSO Protocol: urn:oasis:names:tc:SAML:2.0:protocol
Identity Provider: https://www.sso.anotherdomain.de/simplesaml/saml2/idp/metadata.php
Authentication Time: 2025-07-05T05:14:18Z
Authentication Context Class: https://refeds.org/profile/mfa
Authentication Context Decl: (none)
Attributes
eppn: marcel@anotherdomain.de
mail: marcel@anotherdomain.de
Compare IdP and SP data
So by comparing the attributes two things are more or less obvious: Some attributes (displayName
) didn’t make it to the SP and others changed their name (eduPersonPrincipalName
-> eppn
) – probably by some kind of mapping.
For Shibboleth SPs this takes place in a file usually located at /etc/shibboleth/attribute-map.xml
.
So we could start there using try and error and adding new mappings that might solve the problem. However guessing takes time (and/or quite some luck) so we’ll be going for a more deterministic approach.
Debugging attributes with Shibboleth
This involves setting the Shibboleth logging intensity to DEBUG by changing /etc/shibboleth/shibd.logger:
linux # vi /etc/shibboleth/shibd.logger
# set overall behavior
# Old: log level: INFO
# log4j.rootCategory=INFO, shibd_log, warn_log
# New: log level: DEBUG
log4j.rootCategory=DEBUG, shibd_log, warn_log
<...>
To apply those changes we need to restart shibd
:
linux # systemctl restart shibd
Now during a new login attempt shibd is much more verbose and should report something like this in /var/log/shibboleth/shibd.log
:
linux # tail -f /var/log/shibboleth/shibd.log
<...>
2025-07-05 07:14:18 DEBUG Shibboleth.SSO.SAML2 [3] [app-dev]: SSO profile processing completed successfully
2025-07-05 07:14:18 DEBUG Shibboleth.SSO.SAML2 [3] [app-dev]: extracting pushed attributes...
2025-07-05 07:14:18 DEBUG Shibboleth.AttributeExtractor.XML [3] [app-dev]: unable to extract attributes, unknown XML object type: samlp:Response
2025-07-05 07:14:18 DEBUG Shibboleth.AttributeExtractor.XML [3] [app-dev]: skipping NameID with format (urn:oasis:names:tc:SAML:2.0:nameid-format:transient)
2025-07-05 07:14:18 DEBUG Shibboleth.AttributeExtractor.XML [3] [app-dev]: unable to extract attributes, unknown XML object type: saml:AuthnStatement
2025-07-05 07:14:18 DEBUG Shibboleth.AttributeDecoder.Scoped [3] [app-dev]: decoding ScopedAttribute (eppn) from SAML 2 Attribute (urn:oid:1.3.6.1.4.1.5923.1.1.1.6) with 1 value(s)
2025-07-05 07:14:18 INFO Shibboleth.AttributeExtractor.XML [3] [app-dev]: skipping SAML 2.0 Attribute with Name: urn:oid:2.16.840.1.113730.3.1.241
2025-07-05 07:14:18 DEBUG Shibboleth.AttributeDecoder.String [3] [app-dev]: decoding SimpleAttribute (mail) from SAML 2 Attribute (urn:oid:0.9.2342.19200300.100.1.3) with 1 value(s)
2025-07-05 07:14:18 INFO Shibboleth.AttributeExtractor.XML [3] [app-dev]: skipping SAML 2.0 Attribute with Name: urn:oid:1.3.6.1.4.1.5923.1.1.1.11
2025-07-05 07:14:18 DEBUG Shibboleth.AttributeFilter [3] [app-dev]: filtering 2 attribute(s) from (https://www.sso.anotherdomain.de/simplesaml/saml2/idp/metadata.php)
2025-07-05 07:14:18 DEBUG Shibboleth.AttributeFilter [3] [app-dev]: applying filtering rule(s) for attribute (mail) from (https://www.sso.anotherdomain.de/simplesaml/saml2/idp/metadata.php)
2025-07-05 07:14:18 DEBUG Shibboleth.AttributeFilter [3] [app-dev]: applying filtering rule(s) for attribute (eppn) from (https://www.sso.anotherdomain.de/simplesaml/saml2/idp/metadata.php)
<...>
So let’s extract the relevant information here – what attributes were transmitted and what happened to them:
Attribute Name | Attribute OID | Status |
NameID | urn:oasis:names:tc:SAML:2.0:nameid-format:transient | Skipped |
ScopedAttribute (eppn) | urn:oid:1.3.6.1.4.1.5923.1.1.1.6 | Decoded |
urn:oid:2.16.840.1.113730.3.1.241 | Skipped | |
SimpleAttribute (mail) | urn:oid:0.9.2342.19200300.100.1.3 | Decoded |
urn:oid:1.3.6.1.4.1.5923.1.1.1.11 | Skipped |
So basically it tells us what we already know: Only attributes mail
and eppn
made it to our SP (but at least the logs match reality).
Attribute OIDs
But how do we know which attributes are hidden behind those odd urn:oid: numbers?
Well, of course it helps to know that those OIDs are organized hierarchically (and should) be registered somewhere, but basically you can just google them and you’ll find the information you need (I linked the results in the table above).
Attribute Name | Attribute OID |
NameID | urn:oasis:names:tc:SAML:2.0:nameid-format:transient |
displayName | urn:oid:2.16.840.1.113730.3.1.241 |
eduPersonAssurance | urn:oid:1.3.6.1.4.1.5923.1.1.1.11 |
So let’s add some things to /etc/shibboleth/attribute-map.xml
and restart shibd:
linux # vi /etc/shibboleth/attribute-map.xml
<...>
<Attribute name="urn:oid:1.3.6.1.4.1.5923.1.1.1.11" id="eduPersonAssurance"/>
<Attribute name="urn:oid:2.16.840.1.113730.3.1.241" id="displayName"/>
<...>
Now let’s login again and see what our session looks like now (I skipped the first section):
Attributes
displayName: Marcel XYZ
eduPersonAssurance: https://refeds.org/assurance;https://refeds.org/assurance/ID/unique;<...>
eppn: marcel@anotherdomain.de
mail: marcel@anotherdomain.de