如何读取从 IdP 接收到的 SAML 属性值?
How to read value of SAML attribute received from the IdP?
我正在使用 Spring 安全 SAML 1.0.1,我想知道名称为 "eduPersonAffiliation" 的 SAML 属性的值。我编写了一个实现 org.springframework.security.saml.userdetails.SAMLUserDetailsService
接口的 class,在 loadUserBySAML
方法中,我这样做:
@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);
}
getUser
方法需要一个字符串,它应该是已连接用户的登录名。这个问题听起来很愚蠢,但我如何才能访问给定属性名称的属性值呢?我看到一个 org.opensaml.saml2.core.getAttributeValues
方法 returns 一个 List<XMLObject>
。如何使用?
谢谢!
XmlObject 需要一些解包才能使用:
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();
}
您可以遍历 List<XmlObject>
直到找到您需要的属性,然后调用上面的 getAttributeValue(XmlObject) 方法。
根据这些 XmlObject
的实际含义(Attribute、AttributeValue 等),您可能需要一些这个算法完全解压它们:
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");
}
在这种情况下,我使用标准 OID 作为电子邮件地址。实际上,这必须是可配置的,因为各种 IdP 使用不同的命名策略。这适用于 Shibboleth IdP 3。
@StefanRasmusson 的
A Guide to OpenSAML 是让我克服了获取 SAML 概念和能够实施我自己的 SP 之间的障碍的原因。
Scott Cantor 在 shibboleth-users 邮件列表上也对我提供了难以置信的帮助,从配置差距到高级安全架构问题等主题。 OpenSAML 社区(包括 Shibboleth)非常乐于助人且有主见,我喜欢这一点。
另一种访问属性值的解决方案是通过SAMLCredential.getAttributeAsString(字符串名称)
credential.getAttributeAsString(attribute.getName())
我正在使用 Spring 安全 SAML 1.0.1,我想知道名称为 "eduPersonAffiliation" 的 SAML 属性的值。我编写了一个实现 org.springframework.security.saml.userdetails.SAMLUserDetailsService
接口的 class,在 loadUserBySAML
方法中,我这样做:
@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);
}
getUser
方法需要一个字符串,它应该是已连接用户的登录名。这个问题听起来很愚蠢,但我如何才能访问给定属性名称的属性值呢?我看到一个 org.opensaml.saml2.core.getAttributeValues
方法 returns 一个 List<XMLObject>
。如何使用?
谢谢!
XmlObject 需要一些解包才能使用:
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();
}
您可以遍历 List<XmlObject>
直到找到您需要的属性,然后调用上面的 getAttributeValue(XmlObject) 方法。
根据这些 XmlObject
的实际含义(Attribute、AttributeValue 等),您可能需要一些这个算法完全解压它们:
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");
}
在这种情况下,我使用标准 OID 作为电子邮件地址。实际上,这必须是可配置的,因为各种 IdP 使用不同的命名策略。这适用于 Shibboleth IdP 3。
@StefanRasmusson 的 A Guide to OpenSAML 是让我克服了获取 SAML 概念和能够实施我自己的 SP 之间的障碍的原因。
Scott Cantor 在 shibboleth-users 邮件列表上也对我提供了难以置信的帮助,从配置差距到高级安全架构问题等主题。 OpenSAML 社区(包括 Shibboleth)非常乐于助人且有主见,我喜欢这一点。
另一种访问属性值的解决方案是通过SAMLCredential.getAttributeAsString(字符串名称)
credential.getAttributeAsString(attribute.getName())