【问题标题】:SAMLException: NameID element must be present as part of the Subject in the Response message, please enable it in the IDP configurationSAMLException:NameID 元素必须作为响应消息中主题的一部分出现,请在 IDP 配置中启用它
【发布时间】:2014-12-05 12:51:32
【问题描述】:

我正在使用 spring-saml 实现。在 WebSSOProfileConsumerImpl 类中,我可以找到以下代码行,用于检查 SAML 响应的断言中的 nameId。

NameID nameID;
if (subject.getEncryptedID() != null) {
    Assert.notNull(context.getLocalDecrypter(), "Can't decrypt NameID, no decrypter is set in the context");
    nameID = (NameID) context.getLocalDecrypter().decrypt(subject.getEncryptedID());
} else {
    nameID = subject.getNameID();
}

根据代码,很明显 nameId 应该是主题的一部分。但大多数 IDP 包括我正在使用的 IDP 都提到 nameId 可能是主题/属性的一部分。似乎有一些实现在主题中接受 nameId,就像 SimpleSAMLPHP

我收到的主题如下,没有附上nameId

<saml2:Subject>
  <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">  
    <saml2:SubjectConfirmationData Address="91.X.X.X" InResponseTo="XXXX" NotOnOrAfter="2014-10-10T10:34:26.619Z" Recipient="http://localhost:8080/XXXX/saml/SSO"/>
  </saml2:SubjectConfirmation>
</saml2:Subject>

但是,有一个 属性,它的 属性值nameId。为什么不能用这个来代替主题中的那个。

<saml2:Attribute FriendlyName="testID" 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://XXXX/idp/shibboleth" SPNameQualifier="urn:XX:XX:XX">XXXXXXXXXXXXXXXXX=
      </saml2:NameID>
  </saml2:AttributeValue>
</saml2:Attribute>

谁能解释一下为什么 nameIdspring-saml 实现中唯一的 subject 的一部分。

@vschafer 有没有一种方法可以自定义 securityContext.xml 以选择 nameId,它是特定 attribute 的一部分,而不是来自 主题?

【问题讨论】:

  • @vschafer 如果您对这个问题有任何想法,请告诉我?

标签: spring spring-security saml-2.0 assertion spring-saml


【解决方案1】:

Spring SAML 当前要求 NameID 存在。更改这将需要更改代码,并且目前不能仅通过配置来完成。请随时在Spring SAML Jira 中打开功能请求以更改此设置。

【讨论】:

  • @vschafer 感谢您的帮助。当我没有得到一个新的 nameId 对象时,我能够通过创建一个新的 nameId 对象来解决这个问题。
  • 你是如何做到的“当我没有得到一个新的 nameId 对象时,我能够通过创建一个新的 nameId 对象来解决这个问题”你是否修改了 spring-SAML 代码?还是你发现了那个异常然后创建了一个新的nameId?我也面临同样的问题,其中 IDP 无法发送它,但 spring-SAML 需要 nameId
【解决方案2】:

我们在 ADFS 3.0 中遇到了类似的情况。 ADFS 的这种特殊配置根本不提供 NameId。我们通过从 ADFS 请求 UPN 声明,然后将其用作 NameId 来实施解决方法。不过,可插入的 NameIdResolver 会很好,@vschafer。

如果有人感兴趣,请提供解决方法代码:

public class ClaimConstants {

public static final String UPN = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn";
}

 

public class NameIdWebSSOProfileConsumer extends WebSSOProfileConsumerImpl {

@Override
protected void verifySubject(Subject subject, AuthnRequest request, SAMLMessageContext context) throws SAMLException, DecryptionException {
    super.verifySubject(subject, request, context);

    Response response = (Response) context.getInboundSAMLMessage();
    for (EncryptedAssertion ea : response.getEncryptedAssertions()) {
        Assertion assertion = context.getLocalDecrypter().decrypt(ea);

        for (Statement statement : assertion.getStatements()) {
            if (statement instanceof AttributeStatementImpl) {
                for (Attribute attribute : ((AttributeStatementImpl) statement).getAttributes()) {
                    if (ClaimConstants.UPN.equals(attribute.getName())) {
                        NameID nameId = new NameIDBuilder().buildObject();
                        XSAnyImpl xmlObject = (XSAnyImpl) attribute.getAttributeValues().get(0);
                        nameId.setValue(xmlObject.getTextContent());
                        //noinspection unchecked
                        context.setSubjectNameIdentifier(nameId);
                        return;
                    }
                }
            }
        }
    }
}

然后在Spring中照常使用:

<bean id="webSSOprofileConsumer" class="com.example.NameIdWebSSOProfileConsumer"/>

【讨论】:

    猜你喜欢
    • 2016-09-29
    • 2013-06-29
    • 1970-01-01
    • 2016-10-26
    • 2018-09-13
    • 1970-01-01
    • 2011-10-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多