跳到主要内容

Saml 2.0 元数据

QWen Max 中英对照 SAML2 Metadata Saml 2.0 Metadata

Spring Security 可以解析身份认证方元数据 以生成 AssertingPartyMetadata 实例,以及从 RelyingPartyRegistration 实例发布依赖方元数据

解析 <saml2:IDPSSODescriptor> 元数据

您可以解析身份认证方的元数据使用 RelyingPartyRegistrations

当使用 OpenSAML 供应商支持时,生成的 AssertingPartyMetadata 将是 OpenSamlAssertingPartyDetails 类型。这意味着你可以通过以下方式获取底层的 OpenSAML XMLObject:

OpenSamlAssertingPartyDetails details = (OpenSamlAssertingPartyDetails)
registration.getAssertingPartyMetadata();
EntityDescriptor openSamlEntityDescriptor = details.getEntityDescriptor();
java

使用 AssertingPartyMetadataRepository

您还可以通过使用 AssertingPartyMetadataRepository 来比 RelyingPartyRegistrations 更有针对性,这是一个仅允许检索断言方元数据的接口。

这允许三个有价值的功能:

  • 实现可以以一种过期感知的方式刷新断言方元数据

  • RelyingPartyRegistrationRepository 的实现可以更轻松地表达依赖方与其一个或多个相应的断言方之间的关系

  • 实现可以验证元数据签名

例如,OpenSaml4AssertingPartyMetadataRepository 使用 OpenSAML 的 MetadataResolver,该 API 的实现会以一种过期感知的方式定期刷新底层的元数据。

这意味着你现在只需几行代码就可以创建一个可刷新的 RelyingPartyRegistrationRepository

@Component
public class RefreshableRelyingPartyRegistrationRepository
implements IterableRelyingPartyRegistrationRepository {

private final AssertingPartyMetadataRepository metadata =
OpenSamlAssertingPartyMetadataRepository
.fromTrustedMetadataLocation("https://idp.example.org/metadata").build();

@Override
public RelyingPartyRegistration findByRegistrationId(String registrationId) {
AssertingPartyMetadata metadata = this.metadata.findByEntityId(registrationId);
if (metadata == null) {
return null;
}
return applyRelyingParty(metadata);
}

@Override
public Iterator<RelyingPartyRegistration> iterator() {
return StreamSupport.stream(this.metadata.spliterator(), false)
.map(this::applyRelyingParty).iterator();
}

private RelyingPartyRegistration applyRelyingParty(AssertingPartyMetadata metadata) {
return RelyingPartyRegistration.withAssertingPartyMetadata(metadata)
// apply any relying party configuration
.build();
}

}
java
提示

OpenSaml4AssertingPartyMetadataRepository 还提供了一个构造函数,因此你可以提供一个自定义的 MetadataResolver。由于底层的 MetadataResolver 负责过期和刷新,如果你直接使用构造函数,只有在提供了一个实现这些功能的实现类时,你才能获得这些功能。

验证元数据签名

您还可以通过提供适当的 Saml2X509Credential 集合来使用 OpenSaml4AssertingPartyMetadataRepository 验证元数据签名,如下所示:

OpenSamlAssertingPartyMetadataRepository.withMetadataLocation("https://idp.example.org/metadata")
.verificationCredentials((c) -> c.add(myVerificationCredential))
.build();
java
备注

如果未提供凭证,组件将不会执行签名验证。

生成 <saml2:SPSSODescriptor> 元数据

你可以使用 saml2Metadata DSL 方法发布元数据端点,如下所示:

http
// ...
.saml2Login(withDefaults())
.saml2Metadata(withDefaults());
java

您可以使用此元数据端点将您的依赖方注册到您的认证方。这通常只需要找到正确的表单字段来提供元数据端点即可。

默认情况下,元数据端点是 /saml2/metadata,不过它也响应 /saml2/metadata/{registrationId}/saml2/service-provider-metadata/{registrationId}

您可以通过在DSL中调用metadataUrl方法来更改这一点:

.saml2Metadata((saml2) -> saml2.metadataUrl("/saml/metadata"))
java

更改查找 RelyingPartyRegistration 的方式

如果你有其他策略来确定使用哪个 RelyingPartyRegistration,你可以配置自己的 Saml2MetadataResponseResolver,如下所示:

@Bean
Saml2MetadataResponseResolver metadataResponseResolver(RelyingPartyRegistrationRepository registrations) {
RequestMatcherMetadataResponseResolver metadata = new RequestMatcherMetadataResponseResolver(
(id) -> registrations.findByRegistrationId("relying-party"));
metadata.setMetadataFilename("metadata.xml");
return metadata;
}
java