使用 spring-security-saml 在 RP 元数据中包含所需的声明

Posted

技术标签:

【中文标题】使用 spring-security-saml 在 RP 元数据中包含所需的声明【英文标题】:Include required claims in RP metadata using spring-security-saml 【发布时间】:2016-09-27 22:42:43 【问题描述】:

有没有办法使用 spring-security-saml 在依赖方的元数据响应中包含所需的声明?

理想情况下,我想为各种 IdP 提供联合元数据 URL,该 URL 还指定我们需要哪些声明类型作为 RP(即电子邮件地址、名字、姓氏等)。我目前正在使用 ADFS 作为身份提供者进行测试。使用 RP 元数据 URL 通过向导添加信赖方信任时,除了“已接受的声明”选项卡外,大部分信息都是预先填写的。

我尝试手动修改元数据 xml(如 the docs 中指定的)以在 RoleDescriptor 中包含 ClaimTypesRequired 或 ClaimTypesRequested 元素,尽管我不确定要添加什么...我也更愿意坚持使用如果可能,自动生成的元数据。

我对 RP 元数据 URL 的理解是否正确?或者我会更好地向 IdP 提供 URL,然后告诉他们添加额外的声明。

【问题讨论】:

【参考方案1】:

自动生成的 Spring SAML 元数据中的请求声明没有开箱即用的支持。但您可以扩展 MetadataGenerator class 以根据需要导出其他数据。

【讨论】:

【参考方案2】:

感谢 Vladimír 的建议,我扩展了 MetadataGenerator 类以添加 AttributeConsumingService 和 RequestedAttribute 元素,如下所示。我在这里发布它以防万一它对任何人有帮助。

public class MySAMLMetadataGenerator extends MetadataGenerator

   @Override
   protected SPSSODescriptor buildSPSSODescriptor(String entityBaseURL, String entityAlias, boolean requestSigned, boolean wantAssertionSigned, Collection<String> includedNameID)
   
      SPSSODescriptor descriptor = super.buildSPSSODescriptor(entityBaseURL, entityAlias, requestSigned, wantAssertionSigned, includedNameID);
      descriptor.getAttributeConsumingServices().add(generateConsumingService());
      return descriptor;
   

   private AttributeConsumingService generateConsumingService()
   
      SAMLObjectBuilder<AttributeConsumingService> builder = (SAMLObjectBuilder<AttributeConsumingService>) builderFactory.getBuilder(AttributeConsumingService.DEFAULT_ELEMENT_NAME);
      AttributeConsumingService service = builder.buildObject();

      SAMLObjectBuilder<ServiceName> builder2 = (SAMLObjectBuilder<ServiceName>) builderFactory.getBuilder(ServiceName.DEFAULT_ELEMENT_NAME);
      ServiceName serviceName = builder2.buildObject();
      serviceName.setName(new LocalizedString("application name", "en"));
      service.getNames().add(serviceName);

      SAMLObjectBuilder<ServiceDescription> builder3 = (SAMLObjectBuilder<ServiceDescription>) builderFactory.getBuilder(ServiceDescription.DEFAULT_ELEMENT_NAME);
      ServiceDescription serviceDescription = builder3.buildObject();
      serviceDescription.setDescription(new LocalizedString("Application description", "en"));
      service.getDescriptions().add(serviceDescription);

      SAMLObjectBuilder<RequestedAttribute> builder4 = (SAMLObjectBuilder<RequestedAttribute>) builderFactory.getBuilder(RequestedAttribute.DEFAULT_ELEMENT_NAME);
      RequestedAttribute nameId = builder4.buildObject();
      nameId.setIsRequired(true);
      nameId.setFriendlyName("Name ID");
      nameId.setName("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier");
      nameId.setNameFormat("urn:oasis:names:tc:SAML:2.0:attrname-format:uri");
      service.getRequestAttributes().add(nameId);

      RequestedAttribute email = builder4.buildObject();
      email.setIsRequired(true);
      email.setFriendlyName("E-Mail Address");
      email.setName("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress");
      email.setNameFormat("urn:oasis:names:tc:SAML:2.0:attrname-format:uri");
      service.getRequestAttributes().add(email);

      RequestedAttribute givenName = builder4.buildObject();
      givenName.setIsRequired(true);
      givenName.setFriendlyName("Given Name");
      givenName.setName("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname");
      givenName.setNameFormat("urn:oasis:names:tc:SAML:2.0:attrname-format:uri");
      service.getRequestAttributes().add(givenName);

      RequestedAttribute surname = builder4.buildObject();
      //surname.setIsRequired(true);
      surname.setFriendlyName("Surname");
      surname.setName("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname");
      surname.setNameFormat("urn:oasis:names:tc:SAML:2.0:attrname-format:uri");
      service.getRequestAttributes().add(surname);

      service.setIndex(1);

      return service;
   

不幸的是,Microsoft ADFS 服务器doesn't seem to support 这些属性用于自动设置声明。所以不要浪费时间尝试让它像我一样工作!

【讨论】:

以上是关于使用 spring-security-saml 在 RP 元数据中包含所需的声明的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 spring-security-saml2 配置服务提供者以使用 EncryptedAssertions?

元数据刷新死锁(spring-security-saml)

生成 SP 元数据时出现意外的堆栈跟踪表单 Spring-Security-SAML?

SAML 注销时的 ADFS NullReference 异常(事件 303)

如何处理具有相同实体 ID 的两个 IDP

spring security saml使用哪个密钥?