对于最新的稳定版本,请使用 Spring Security 6.5.3! |
生产<saml2:AuthnRequest>
s
如前所述,Spring Security 的 SAML 2.0 支持会产生一个<saml2:AuthnRequest>
开始与断言方进行身份验证。
Spring Security 部分通过注册Saml2WebSsoAuthenticationRequestFilter
在过滤器链中。
默认情况下,此筛选器响应终结点/saml2/authenticate/{registrationId}
.
例如,如果您被部署到rp.example.com
并且您为注册提供了 IDokta
,您可以导航到:
结果将是一个重定向,其中包含一个SAMLRequest
包含 signed、deflated 和 encoded 的参数<saml2:AuthnRequest>
.
更改<saml2:AuthnRequest>
存储
Saml2WebSsoAuthenticationRequestFilter
使用Saml2AuthenticationRequestRepository
要持久化AbstractSaml2AuthenticationRequest
实例之前发送<saml2:AuthnRequest>
到主张方。
此外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 将对<saml2:AuthnRequest>
用rsa-sha256
,尽管一些断言方将需要不同的算法,如其元数据所示。
您可以根据断言方的元数据使用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();
上面的代码段使用 OpenSAMLSignatureConstants class 来提供算法名称。
但是,这只是为了方便。
由于数据类型是String ,您可以直接提供算法的名称。 |
一些断言方要求<saml2:AuthnRequest>
被邮寄。
这可以通过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
默认情况下。
您可以自定义 OpenSAML 的AuthnRequest
通过发布OpenSaml4AuthenticationRequestResolver
作为@Bean
这样:
-
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
}