跳到主要内容

生成 <saml2:AuthnRequest>

QWen Max 中英对照 SAML2 Authentication Requests Producing <saml2:AuthnRequest>s

正如前面所述,Spring Security 的 SAML 2.0 支持生成一个 <saml2:AuthnRequest> 来开始与声明方的身份验证。

Spring Security 通过将 Saml2WebSsoAuthenticationRequestFilter 注册到过滤器链中部分实现了这一点。此过滤器默认响应端点 /saml2/authenticate/{registrationId}/saml2/authenticate?registrationId={registrationId}

例如,如果你被部署到 [rp.example.com](https://rp.example.com) 并且你给你的注册一个 okta 的 ID,你可以导航到:

[rp.example.org/saml2/authenticate/okta](https://rp.example.org/saml2/authenticate/okta)

结果将是一个重定向,其中包含一个 SAMLRequest 参数,该参数包含已签名、压缩和编码的 <saml2:AuthnRequest>

配置 <saml2:AuthnRequest> 端点

要配置与默认设置不同的端点,您可以在 saml2Login 中设置值:

@Bean
SecurityFilterChain filterChain(HttpSecurity http) {
http
.saml2Login((saml2) -> saml2
.authenticationRequestUriQuery("/custom/auth/sso?peerEntityID={registrationId}")
);
return new CustomSaml2AuthenticationRequestRepository();
}
java

更改 <saml2:AuthnRequest> 的存储方式

Saml2WebSsoAuthenticationRequestFilter 使用 Saml2AuthenticationRequestRepository发送 <saml2:AuthnRequest> 给断言方之前,保存一个 AbstractSaml2AuthenticationRequest 实例。

此外,Saml2WebSsoAuthenticationFilterSaml2AuthenticationTokenConverter 使用 Saml2AuthenticationRequestRepository 来加载任何 AbstractSaml2AuthenticationRequest,作为验证 <saml2:Response> 的一部分。

默认情况下,Spring Security 使用 HttpSessionSaml2AuthenticationRequestRepository,它将 AbstractSaml2AuthenticationRequest 存储在 HttpSession 中。

如果你有一个自定义的 Saml2AuthenticationRequestRepository 实现,你可以通过将其暴露为一个 @Bean 来进行配置,如下例所示:

@Bean
Saml2AuthenticationRequestRepository<AbstractSaml2AuthenticationRequest> authenticationRequestRepository() {
return new CustomSaml2AuthenticationRequestRepository();
}
java

更改 <saml2:AuthnRequest> 的发送方式

默认情况下,Spring Security 会对每个 <saml2:AuthnRequest> 进行签名,并通过 GET 请求将其发送到断言方。

许多声明方不需要签名的 <saml2:AuthnRequest>。这可以通过 RelyingPartyRegistrations 自动配置,或者你可以手动提供,如下所示:

spring:
security:
saml2:
relyingparty:
okta:
identityprovider:
entity-id: ...
singlesignon.sign-request: false
yaml

否则,你需要向 RelyingPartyRegistration#signingX509Credentials 指定一个私钥,以便 Spring Security 在发送之前可以对 <saml2:AuthnRequest> 进行签名。

默认情况下,Spring Security 将使用 rsa-sha256<saml2:AuthnRequest> 进行签名,不过某些断言方可能会在其元数据中要求使用不同的算法。

或者,你可以手动提供:

String metadataLocation = "classpath:asserting-party-metadata.xml";
RelyingPartyRegistration relyingPartyRegistration = RelyingPartyRegistrations.fromMetadataLocation(metadataLocation)
// ...
.assertingPartyMetadata((party) -> party
// ...
.signingAlgorithms((sign) -> sign.add(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA512))
)
.build();
java
备注

上面的代码片段使用了 OpenSAML 的 SignatureConstants 类来提供算法名称。但这只是为了方便。由于数据类型是 String,你可以直接提供算法名称。

一些声明方要求 <saml2:AuthnRequest> 通过 POST 方式发送。这可以通过 RelyingPartyRegistrations 自动配置,或者你可以手动提供,如下所示:

RelyingPartyRegistration relyingPartyRegistration = RelyingPartyRegistration.withRegistrationId("okta")
// ...
.assertingPartyMetadata(party -> party
// ...
.singleSignOnServiceBinding(Saml2MessageBinding.POST)
)
.build();
java

自定义 OpenSAML 的 AuthnRequest 实例

你可能有多种原因需要调整 AuthnRequest。例如,你可能希望将 ForceAuthN 设置为 true,而 Spring Security 默认将其设置为 false

你可以通过发布一个 OpenSaml4AuthenticationRequestResolver 作为 @Bean 来自定义 OpenSAML 的 AuthnRequest,如下所示:

@Bean
Saml2AuthenticationRequestResolver authenticationRequestResolver(RelyingPartyRegistrationRepository registrations) {
RelyingPartyRegistrationResolver registrationResolver =
new DefaultRelyingPartyRegistrationResolver(registrations);
OpenSaml4AuthenticationRequestResolver authenticationRequestResolver =
new OpenSaml4AuthenticationRequestResolver(registrationResolver);
authenticationRequestResolver.setAuthnRequestCustomizer((context) -> context
.getAuthnRequest().setForceAuthn(true));
return authenticationRequestResolver;
}
java