SAMLException: NameID element must be present as part of the Subject in the Response message, please enable it in the IDP configuration

人盡茶涼 提交于 2019-12-04 10:28:14

Spring SAML currently requires NameID to be present. Changing this would require code changes and cannot be currently done with configuration only. Please feel free to open a feature request for changing this in Spring SAML Jira.

We had a similar scenario with ADFS 3.0. This particular configuration of ADFS didn't supply NameId at all. We implemented a workaround by requesting an UPN claim from ADFS, and then using that as NameId. A pluggable NameIdResolver would be nice though, @vschafer.

Code for workaround if anyone's interested:

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;
                    }
                }
            }
        }
    }
}

And then use in Spring as normal:

<bean id="webSSOprofileConsumer" class="com.example.NameIdWebSSOProfileConsumer"/>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!