java - 如何读取从 IdP 接收到的 SAML 属性值?

标签 java spring-security spring-saml

我正在使用 Spring Security SAML 1.0.1,我想知道名称为“eduPersonAffiliation”的 SAML 属性的值。我编写了一个实现 org.springframework.security.saml.userdetails.SAMLUserDetailsService 的类界面和 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返回 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确实是(AttributeAttributeValue 等)您可能需要此算法的某些部分才能完全解压它们:

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)非常乐于助人且有主见,我喜欢这一点。

关于java - 如何读取从 IdP 接收到的 SAML 属性值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33677819/

相关文章:

authentication - Grails Spring Security Core 创建新用户

java - 如何在没有 SAML 的情况下在多个 Spring Security Web 应用程序上使用 SSO?

java - Hamcrest 中的 JUnit Assert#assertSame 等价物

java - 异常处理,创建日志并在JAVA中发生异常后继续程序

java - 无法将 getNamedQuery 结果转换为表类

java - Spring Security 更改 spring_security_login 表单

java - 在 Java 中使用 Rest API 上传文件

facebook - 接受 facebook 登录到我的 REST API

spring-security - SAML 漏洞说明 VU#475445 - Spring Secucity SAML2 是否受到影响?

java - 仅检查 SAML 身份验证,不转发