我使用 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包括我正在使用的那个ID提及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>
任何人都可以解释 nameId 仅在 spring-saml 实施中属于主题的原因。
@vschafer有没有办法自定义 securityContext.xml 来选择 nameId ,它是特定属性的一部分,而不是来自受试者
答案 0 :(得分:3)
我们在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"/>
答案 1 :(得分:2)
Spring SAML目前需要NameID
才能出现。更改此项将需要更改代码,目前无法仅通过配置完成。请随意在Spring SAML Jira中打开更改此功能的功能请求。