生成 <saml2:AuthnRequest>
本站(springdoc.cn)中的内容来源于 spring.io ,原始版权归属于 spring.io。由 springdoc.cn 进行翻译,整理。可供个人学习、研究,未经许可,不得进行任何转载、商用或与之相关的行为。 商标声明:Spring 是 Pivotal Software, Inc. 在美国以及其他国家的商标。 |
如前所述,Spring Security 的 SAML 2.0 支持产生一个 <saml2:AuthnRequest>
来开始与断言方进行认证。
Spring Security通过在过滤器链中注册 Saml2WebSsoAuthenticationRequestFilter
部分实现了这一点。这个过滤器默认响应端点 /saml2/authenticate/{registrationId}
。
例如,如果你被部署到 rp.example.com
,并且你给你的注册的ID是 okta
,你可以导航到:
而结果将是一个重定向,其中包括一个 SAMLRequest
参数,包含经过签名、解压缩和编码的 <saml2:AuthnRequest>
。
改变 <saml2:AuthnRequest>
的存储方式
Saml2WebSsoAuthenticationRequestFilter
在向断言方 发送 <saml2:AuthnRequest>
之前,使用 Saml2AuthenticationRequestRepository
来持久化一个 AbstractSaml2AuthenticationRequest
实例。
此外,Saml2WebSsoAuthenticationFilter
和 Saml2AuthenticationTokenConverter
使用 Saml2AuthenticationRequestRepository
来加载任何 AbstractSaml2AuthenticationRequest
作为 验证 <saml2:Response>
的一部分。
默认情况下,Spring Security 使用一个 HttpSessionSaml2AuthenticationRequestRepository
,它将 AbstractSaml2AuthenticationRequest
存储在 HttpSession
中。
如果你有一个 Saml2AuthenticationRequestRepository
的自定义实现,你可以通过将其暴露为一个 @Bean
来配置它,如下例所示。
-
Java
-
Kotlin
@Bean
Saml2AuthenticationRequestRepository<AbstractSaml2AuthenticationRequest> authenticationRequestRepository() {
return new CustomSaml2AuthenticationRequestRepository();
}
@Bean
open fun authenticationRequestRepository(): Saml2AuthenticationRequestRepository<AbstractSaml2AuthenticationRequest> {
return CustomSaml2AuthenticationRequestRepository()
}
改变 <saml2:AuthnRequest>
的发送方式
默认情况下,Spring Security 对每个 <saml2:AuthnRequest>
进行签名,并将其作为 GET 发送到断言方。
许多断言方不需要签名的 <saml2:AuthnRequest>
。这可以通过 RelyingPartyRegistrations
自动配置,或者你可以手动提供,像这样。
-
Boot
-
Java
-
Kotlin
spring:
security:
saml2:
relyingparty:
okta:
identityprovider:
entity-id: ...
singlesignon.sign-request: false
RelyingPartyRegistration relyingPartyRegistration = RelyingPartyRegistration.withRegistrationId("okta")
// ...
.assertingPartyDetails(party -> party
// ...
.wantAuthnRequestsSigned(false)
)
.build();
var relyingPartyRegistration: RelyingPartyRegistration =
RelyingPartyRegistration.withRegistrationId("okta")
// ...
.assertingPartyDetails { party: AssertingPartyDetails.Builder -> party
// ...
.wantAuthnRequestsSigned(false)
}
.build();
否则,你需要为 RelyingPartyRegistration#signingX509Credentials
指定一个私钥,以便 Spring Security 在发送前签署 <saml2:AuthnRequest>
。
默认情况下,Spring Security 将使用 rsa-sha256
对 <saml2:AuthnRequest>
进行签名,尽管一些断言方需要不同的算法,正如他们的元数据中指出的那样。
你可以 使用 RelyingPartyRegistrations
根据断言方的元数据 来配置该算法。
或者,你可以手动提供它。
-
Java
-
Kotlin
String metadataLocation = "classpath:asserting-party-metadata.xml";
RelyingPartyRegistration relyingPartyRegistration = RelyingPartyRegistrations.fromMetadataLocation(metadataLocation)
// ...
.assertingPartyDetails((party) -> party
// ...
.signingAlgorithms((sign) -> sign.add(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA512))
)
.build();
var metadataLocation = "classpath:asserting-party-metadata.xml"
var relyingPartyRegistration: RelyingPartyRegistration =
RelyingPartyRegistrations.fromMetadataLocation(metadataLocation)
// ...
.assertingPartyDetails { party: AssertingPartyDetails.Builder -> party
// ...
.signingAlgorithms { sign: MutableList<String?> ->
sign.add(
SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA512
)
}
}
.build();
上面的片段使用OpenSAML SignatureConstants 类来提供算法名称。但是,这只是为了方便。由于数据类型是 String ,你可以直接提供算法的名称。
|
一些断言方要求 <saml2:AuthnRequest>
被POST。这可以通过 RelyingPartyRegistrations
自动配置,或者你可以手动提供,像这样。
-
Java
-
Kotlin
RelyingPartyRegistration relyingPartyRegistration = RelyingPartyRegistration.withRegistrationId("okta")
// ...
.assertingPartyDetails(party -> party
// ...
.singleSignOnServiceBinding(Saml2MessageBinding.POST)
)
.build();
var relyingPartyRegistration: RelyingPartyRegistration? =
RelyingPartyRegistration.withRegistrationId("okta")
// ...
.assertingPartyDetails { party: AssertingPartyDetails.Builder -> party
// ...
.singleSignOnServiceBinding(Saml2MessageBinding.POST)
}
.build()
自定义 OpenSAML 的 AuthnRequest
实例
你可能想调整一个 AuthnRequest
,有很多原因。例如,你可能希望 ForceAuthN
被设置为 true
,而 Spring Security 默认将其设置为 false
。
你可以通过发布一个 OpenSaml4AuthenticationRequestResolver
作为 @Bean
来定制 OpenSAML 的 AuthnRequest
的元素,就像这样。
-
Java
-
Kotlin
@Bean
Saml2AuthenticationRequestResolver authenticationRequestResolver(RelyingPartyRegistrationRepository registrations) {
RelyingPartyRegistrationResolver registrationResolver =
new DefaultRelyingPartyRegistrationResolver(registrations);
OpenSaml4AuthenticationRequestResolver authenticationRequestResolver =
new OpenSaml4AuthenticationRequestResolver(registrationResolver);
authenticationRequestResolver.setAuthnRequestCustomizer((context) -> context
.getAuthnRequest().setForceAuthn(true));
return authenticationRequestResolver;
}
@Bean
fun authenticationRequestResolver(registrations : RelyingPartyRegistrationRepository) : Saml2AuthenticationRequestResolver {
val registrationResolver : RelyingPartyRegistrationResolver =
new DefaultRelyingPartyRegistrationResolver(registrations)
val authenticationRequestResolver : OpenSaml4AuthenticationRequestResolver =
new OpenSaml4AuthenticationRequestResolver(registrationResolver)
authenticationRequestResolver.setAuthnRequestCustomizer((context) -> context
.getAuthnRequest().setForceAuthn(true))
return authenticationRequestResolver
}