SAMLException: элемент NameID должен присутствовать как часть темы в ответном сообщении, включите его в конфигурации IDP.

Я использую реализацию spring-saml. В классе WebSSOProfileConsumerImpl я смог найти следующие строки кода, которые проверяют nameId в утверждении ответа SAML.

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, включая тот, который я использую, упоминают, что nameId может быть частью объекта / атрибута. Похоже, что есть несколько реализаций, которые принимают nameId в теме, как SimpleSAMLPHP.

Тема, которую я получаю, выглядит следующим образом, и в ней не указано имяId

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

Может ли кто-нибудь объяснить, почему nameId является частью только subject в реализации spring-saml.

@vschafer Есть ли способ настроить securityContext.xml, чтобы выбрать nameId, который является частью определенного атрибута, а не из темы ?


person SM KUMAR    schedule 10.10.2014    source источник
comment
@vschafer Не могли бы вы сообщить мне, есть ли у вас какие-либо идеи по этому вопросу?   -  person SM KUMAR    schedule 13.10.2014


Ответы (2)


В настоящее время Spring SAML требует наличия NameID. Изменение этого потребует изменения кода и в настоящее время не может быть выполнено только с конфигурацией. Не стесняйтесь открывать запрос функции для изменения этого в Spring SAML Jira.

person Vladimír Schäfer    schedule 13.10.2014
comment
@vschafer Спасибо за помощь. Мне удалось обойти проблему, создав новый объект nameId, когда я его не получил. - person SM KUMAR; 15.10.2014
comment
Как мне удалось обойти проблему, создав новый объект nameId, когда я его не получил. Вы изменили код Spring-SAML? или вы поймали это исключение, а затем создали новый nameId? Я также сталкиваюсь с той же проблемой, когда IDP не может отправить его, но для Spring-SAML требуется nameId - person Rahul; 20.05.2015

У нас был аналогичный сценарий с ADFS 3.0. Эта конкретная конфигурация ADFS вообще не предоставляла NameId. Мы реализовали обходной путь, запросив UPN-утверждение из ADFS, а затем используя его как 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"/>
person gogstad    schedule 11.04.2016