I'm using Spring Security SAML 1.0.1, and I want to know the value of the SAML attribute whose name is "eduPersonAffiliation". I've coded a class which implements the org.springframework.security.saml.userdetails.SAMLUserDetailsService
interface and in the loadUserBySAML
method, I'm doing this:
@Override
public Object loadUserBySAML(SAMLCredential credential) throws UsernameNotFoundException {
String eduPersonAffiliationAttributeName = "";
// We need to use the "name" of the attribute to retrieve the value (not the friendly name)
for (Attribute attribute : credential.getAttributes()) {
if ("eduPersonAffiliation".equals(attribute.getFriendlyName())) {
eduPersonAffiliationAttributeName = attribute.getName();
}
}
Person user = usersService.getUser(
credential.getAttribute(eduPersonAffiliationAttributeName).WHAT_TO_CALL_HERE?);
return loadUserByUser(user);
}
The getUser
method expects a String which should be the login of the connected user. The question sounds stupid but how can I access the attribute value given the attribute name? I see a org.opensaml.saml2.core.getAttributeValues
method that returns a List<XMLObject>
. How to use it?
Thanks!
A SAML (Security Assertion Markup Language) attribute assertion contains information about a user in the form of a series of attributes. The Retrieve from SAML Attribute Assertion can retrieve these attributes and store them in the attribute.
Which three 3 data items must the IdP send in a SAML response? SAML federations are created in the Resilient platform using the resutil tool. To create the SAML federation, you need the following information from your Identity Provider: Identity Provider Authentication URL. Identity Provider public certificate.
Here's the flow: 1) User accesses main website and chooses to log in. 2) User enters login information and submits 3) System validates credentials, generates a SAML response and redirects user to the new tool along with the SAML response as a POST variable.
XmlObject requires some unpacking to work with:
private String getAttributeValue(XMLObject attributeValue)
{
return attributeValue == null ?
null :
attributeValue instanceof XSString ?
getStringAttributeValue((XSString) attributeValue) :
attributeValue instanceof XSAnyImpl ?
getAnyAttributeValue((XSAnyImpl) attributeValue) :
attributeValue.toString();
}
private String getStringAttributeValue(XSString attributeValue)
{
return attributeValue.getValue();
}
private String getAnyAttributeValue(XSAnyImpl attributeValue)
{
return attributeValue.getTextContent();
}
You can loop over the List<XmlObject>
until you find the attribute you need to and then call the getAttributeValue(XmlObject) method above.
Depending on what these XmlObject
s really are (Attribute, AttributeValue, etc.) you may need some portion of this algorithm to unpack them fully:
private final static String USERNAME_ATTRIBUTE_NAME = "urn:oid:0.9.2342.19200300.100.1.3"
private String getUsername(Assertion assertion)
{
for (AttributeStatement attributeStatement : assertion.getAttributeStatements())
{
for (Attribute attribute : attributeStatement.getAttributes())
{
if (USERNAME_ATTRIBUTE_NAME.equals(attribute.getName()))
{
List<XMLObject> attributeValues = attribute.getAttributeValues();
if (!attributeValues.isEmpty())
{
return getAttributeValue(attributeValues.get(0));
}
}
}
}
throw new IllegalArgumentException("no username attribute found");
}
In this case I'm using the standard OID for email address. In practice this has to be configurable as various IdP's use different naming strategies. This worked with Shibboleth IdP 3.
@StefanRasmusson's A Guide to OpenSAML is what got me past the hump between getting SAML concepts and being able to implement my own SP.
Scott Cantor was also incredibly helpful to me on the shibboleth-users mailing list from topics ranging for configuration gaps to high-level security architectural questions. The OpenSAML community (including Shibboleth) are very helpful and opinionated and I like that.
Another solution to access an attribute value is via SAMLCredential.getAttributeAsString(String name)
credential.getAttributeAsString(attribute.getName())
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With