最新の安定バージョンについては、Spring Security 6.5.3 を使用してください! |
SAML 移行
次の手順は、SAML 2.0 の構成方法に関する変更に関連しています。
OpenSAML 4 を使用する
OpenSAML 3 はサポートが終了しました。そのため、Spring Security 6 はそのサポートを中止し、OpenSAML ベースラインを 4 に上げました。
アップグレードの準備として、OpenSAML 3 ではなく 4 に依存するように pom を更新します。
<dependencyManagement>
<dependency>
<groupId>org.opensaml</groupId>
<artifactId>opensaml-core</artifactId>
<version>4.2.1</version>
</dependency>
<dependency>
<groupId>org.opensaml</groupId>
<artifactId>opensaml-saml-api</artifactId>
<version>4.2.1</version>
</dependency>
<dependency>
<groupId>org.opensaml</groupId>
<artifactId>opensaml-saml-impl</artifactId>
<version>4.2.1</version>
</dependency>
</dependencyManagement>
dependencies {
constraints {
api "org.opensaml:opensaml-core:4.2.1"
api "org.opensaml:opensaml-saml-api:4.2.1"
api "org.opensaml:opensaml-saml-impl:4.2.1"
}
}
Spring Security 6 の SAML サポートに更新するには、少なくとも OpenSAML 4.1.1 を使用する必要があります。
OpenSaml4AuthenticationProvider
を使用する
OpenSAML 3 と 4 の両方を同時にサポートするために、Spring Security は OpenSamlAuthenticationProvider
と OpenSaml4AuthenticationProvider
をリリースしました。6.0 では、OpenSAML3 のサポートが削除されたため、OpenSamlAuthenticationProvider
も削除されました。
OpenSamlAuthenticationProvider
のすべてのメソッドが OpenSaml4AuthenticationProvider
に 1 対 1 で移植されたわけではありません。そのため、チャレンジするには多少の調整が必要になります。
OpenSamlAuthenticationProvider
の次の代表的な使用箇所を検討してください。
Java
Kotlin
OpenSamlAuthenticationProvider versionThree = new OpenSamlAuthenticationProvider();
versionThree.setAuthoritiesExtractor(myAuthoritiesExtractor);
versionThree.setResponseTimeValidationSkew(myDuration);
val versionThree: OpenSamlAuthenticationProvider = OpenSamlAuthenticationProvider()
versionThree.setAuthoritiesExtractor(myAuthoritiesExtractor)
versionThree.setResponseTimeValidationSkew(myDuration)
これは次のように変更する必要があります。
Java
Kotlin
Converter<ResponseToken, Saml2Authentication> delegate = OpenSaml4AuthenticationProvider
.createDefaultResponseAuthenticationConverter();
OpenSaml4AuthenticationProvider versionFour = new OpenSaml4AuthenticationProvider();
versionFour.setResponseAuthenticationConverter((responseToken) -> {
Saml2Authentication authentication = delegate.convert(responseToken);
Assertion assertion = responseToken.getResponse().getAssertions().get(0);
AuthenticatedPrincipal principal = (AuthenticatedPrincipal) authentication.getPrincipal();
Collection<GrantedAuthority> authorities = myAuthoritiesExtractor.convert(assertion);
return new Saml2Authentication(principal, authentication.getSaml2Response(), authorities);
});
Converter<AssertionToken, Saml2ResponseValidationResult> validator = OpenSaml4AuthenticationProvider
.createDefaultAssertionValidatorWithParameters((p) -> p.put(CLOCK_SKEW, myDuration));
versionFour.setAssertionValidator(validator);
val delegate = OpenSaml4AuthenticationProvider.createDefaultResponseAuthenticationConverter()
val versionFour = OpenSaml4AuthenticationProvider()
versionFour.setResponseAuthenticationConverter({
responseToken -> {
val authentication = delegate.convert(responseToken)
val assertion = responseToken.getResponse().getAssertions().get(0)
val principal = (AuthenticatedPrincipal) authentication.getPrincipal()
val authorities = myAuthoritiesExtractor.convert(assertion)
return Saml2Authentication(principal, authentication.getSaml2Response(), authorities)
}
})
val validator = OpenSaml4AuthenticationProvider
.createDefaultAssertionValidatorWithParameters({ p -> p.put(CLOCK_SKEW, myDuration) })
versionFour.setAssertionValidator(validator)
SAML 2.0 Converter
コンストラクターの使用をやめる
Spring Security の SAML 2.0 サポートの初期リリースでは、Saml2MetadataFilter
および Saml2AuthenticationTokenConverter
は型 Converter
のコンストラクターと共に提供されました。このレベルの抽象化により、クラスを進化させるのが難しくなったため、専用のインターフェース RelyingPartyRegistrationResolver
が後のリリースで導入されました。
6.0 では、Converter
コンストラクターが削除されています。5.8 でこれに備えるには、Converter<HttpServletRequest, RelyingPartyRegistration>
を実装するクラスを変更して、代わりに RelyingPartyRegistrationResolver
を実装します。
Saml2AuthenticationRequestResolver
を使用するように変更
Saml2AuthenticationContextResolver
と Saml2AuthenticationRequestFactory
は、必要とする Saml2WebSsoAuthenticationRequestFilter
と同様に 6.0 で削除されます。それらは Saml2AuthenticationRequestResolver
と Saml2WebSsoAuthenticationRequestFilter
の新しいコンストラクターに置き換えられます。新しいインターフェースは、2 つのクラス間の不要なトランスポートオブジェクトを削除します。
ほとんどのアプリケーションは何もする必要はありません。ただし、Saml2AuthenticationRequestContextResolver
または Saml2AuthenticationRequestFactory
を使用または構成する場合は、次の手順を試して、代わりに Saml2AuthenticationRequestResolver
を使用して変換してください。
setAuthenticationRequestContextConverter
の代わりに setAuthnRequestCustomizer
を使用する
たとえば、次のように OpenSaml4AuthenticationReqeustFactory#setAuthenticationRequestContextConverter
を呼び出している場合:
Java
@Bean
Saml2AuthenticationRequestFactory authenticationRequestFactory() {
OpenSaml4AuthenticationRequestFactory factory = new OpenSaml4AuthenticationRequestFactory();
factory.setAuthenticationRequestContextConverter((context) -> {
AuthnRequestBuilder authnRequestBuilder = ConfigurationService.get(XMLObjectProviderRegistry.class)
.getBuilderFactory().getBuilder(AuthnRequest.DEFAULT_ELEMENT_NAME);
IssuerBuilder issuerBuilder = ConfigurationService.get(XMLObjectProviderRegistry.class)
.getBuilderFactory().getBuilder(Issuer.DEFAULT_ELEMENT_NAME);
tring issuer = context.getIssuer();
String destination = context.getDestination();
String assertionConsumerServiceUrl = context.getAssertionConsumerServiceUrl();
String protocolBinding = context.getRelyingPartyRegistration().getAssertionConsumerServiceBinding().getUrn();
AuthnRequest auth = authnRequestBuilder.buildObject();
auth.setID("ARQ" + UUID.randomUUID().toString().substring(1));
auth.setIssueInstant(Instant.now());
auth.setForceAuthn(Boolean.TRUE);
auth.setIsPassive(Boolean.FALSE);
auth.setProtocolBinding(SAMLConstants.SAML2_POST_BINDING_URI);
Issuer iss = issuerBuilder.buildObject();
iss.setValue(issuer);
auth.setIssuer(iss);
auth.setDestination(destination);
auth.setAssertionConsumerServiceURL(assertionConsumerServiceUrl);
});
return factory;
}
ForceAuthn が true
に設定されていることを確認するには、代わりに次のようにします。
Java
@Bean
Saml2AuthenticationRequestResolver authenticationRequestResolver(RelyingPartyRegistrationResolver registrations) {
OpenSaml4AuthenticationRequestResolver reaolver = new OpenSaml4AuthenticationRequestResolver(registrations);
resolver.setAuthnRequestCustomizer((context) -> context.getAuthnRequest().setForceAuthn(Boolean.TRUE));
return resolver;
}
また、setAuthnRequestCustomizer
は HttpServletRequest
に直接アクセスできるため、Saml2AuthenticationRequestContextResolver
は必要ありません。setAuthnRequestCustomizer
を使用して、必要なこの情報を HttpServletRequest
から直接読み取るだけです。
setProtocolBinding
の代わりに setAuthnRequestCustomizer
を使用する
代わりに:
Java
@Bean
Saml2AuthenticationRequestFactory authenticationRequestFactory() {
OpenSaml4AuthenticationRequestFactory factory = new OpenSaml4AuthenticationRequestFactory();
factory.setProtocolBinding("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST")
return factory;
}
できるよ:
Java
@Bean
Saml2AuthenticationRequestResolver authenticationRequestResolver() {
OpenSaml4AuthenticationRequestResolver reaolver = new OpenSaml4AuthenticationRequestResolver(registrations);
resolver.setAuthnRequestCustomizer((context) -> context.getAuthnRequest()
.setProtocolBinding("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"));
return resolver;
}
Spring Security は認証のために |
最新の Saml2AuthenticationToken
コンストラクターを使用する
初期のリリースでは、Saml2AuthenticationToken
はコンストラクターのパラメーターとしていくつかの個別の設定を取りました。これにより、新しいパラメーターを追加する必要があるたびに問題が発生しました。これらの設定のほとんどは RelyingPartyRegistration
の一部であるため、RelyingPartyRegistration
を提供できる新しいコンストラクターが追加され、コンストラクターがより安定しました。また、OAuth2LoginAuthenticationToken
の設計により近いという点でも価値があります。
Saml2WebSsoAuthenticationFilter
が行うため、ほとんどのアプリケーションはこのクラスを直接構築しません。ただし、アプリケーションで作成する場合は、次のように変更してください。
Java
Kotlin
new Saml2AuthenticationToken(saml2Response, registration.getSingleSignOnServiceLocation(),
registration.getAssertingParty().getEntityId(), registration.getEntityId(), registration.getCredentials())
Saml2AuthenticationToken(saml2Response, registration.getSingleSignOnServiceLocation(),
registration.getAssertingParty().getEntityId(), registration.getEntityId(), registration.getCredentials())
to:
Java
Kotlin
new Saml2AuthenticationToken(saml2Response, registration)
Saml2AuthenticationToken(saml2Response, registration)
RelyingPartyRegistration
の更新されたメソッドを使用する
Spring Security の SAML サポートの初期リリースでは、特定の RelyingPartyRegistration
メソッドとその機能の意味が曖昧でした。RelyingPartyRegistration
に機能が追加されるにつれて、メソッド名を仕様言語に合わせた名前に変更して、このあいまいさを明確にする必要が生じました。
RelyingPartyRegstration
の廃止されたメソッドは削除されました。それに備えて、次の RelyingPartyRegistration
の代表的な使用箇所を検討してください。
Java
Kotlin
String idpEntityId = registration.getRemoteIdpEntityId();
String assertionConsumerServiceUrl = registration.getAssertionConsumerServiceUrlTemplate();
String idpWebSsoUrl = registration.getIdpWebSsoUrl();
String localEntityId = registration.getLocalEntityIdTemplate();
List<Saml2X509Credential> verifying = registration.getCredentials().stream()
.filter(Saml2X509Credential::isSignatureVerficationCredential)
.collect(Collectors.toList());
val idpEntityId: String = registration.getRemoteIdpEntityId()
val assertionConsumerServiceUrl: String = registration.getAssertionConsumerServiceUrlTemplate()
val idpWebSsoUrl: String = registration.getIdpWebSsoUrl()
val localEntityId: String = registration.getLocalEntityIdTemplate()
val verifying: List<Saml2X509Credential> = registration.getCredentials()
.filter(Saml2X509Credential::isSignatureVerficationCredential)
これは次のように変更する必要があります。
Java
Kotlin
String assertingPartyEntityId = registration.getAssertingPartyDetails().getEntityId();
String assertionConsumerServiceLocation = registration.getAssertionConsumerServiceLocation();
String singleSignOnServiceLocation = registration.getAssertingPartyDetails().getSingleSignOnServiceLocation();
String entityId = registration.getEntityId();
List<Saml2X509Credential> verifying = registration.getAssertingPartyDetails().getVerificationX509Credentials();
val assertingPartyEntityId: String = registration.getAssertingPartyDetails().getEntityId()
val assertionConsumerServiceLocation: String = registration.getAssertionConsumerServiceLocation()
val singleSignOnServiceLocation: String = registration.getAssertingPartyDetails().getSingleSignOnServiceLocation()
val entityId: String = registration.getEntityId()
val verifying: List<Saml2X509Credential> = registration.getAssertingPartyDetails().getVerificationX509Credentials()
変更されたすべてのメソッドの完全なリストについては、RelyingPartyRegistration
の JavaDoc (Javadoc) を参照してください。