<saml2:AuthnRequest> の作成

前述のように、Spring Security の SAML 2.0 サポートは、アサーティングパーティとの認証を開始するための <saml2:AuthnRequest> を生成します。

Spring Security は、Saml2WebSsoAuthenticationRequestFilter をフィルターチェーンに登録することにより、これを部分的に実現します。このフィルターは、デフォルトでエンドポイント /saml2/authenticate/{registrationId} に応答します。

例: rp.example.com (英語)  にデプロイされ、登録に okta の ID を付与した場合、次の場所に移動できます。

結果は、署名され、デフレートされ、エンコードされた <saml2:AuthnRequest> を含む SAMLRequest パラメーターを含むリダイレクトになります。

<saml2:AuthnRequest> の保存方法の変更

Saml2WebSsoAuthenticationRequestFilter は、Saml2AuthenticationRequestRepository を使用して AbstractSaml2AuthenticationRequest インスタンスを永続化してから、<saml2:AuthnRequest> をアサート側に送信します。

さらに、Saml2WebSsoAuthenticationFilter および Saml2AuthenticationTokenConverter は、<saml2:Response> の認証の一部として、Saml2AuthenticationRequestRepository を使用して任意の AbstractSaml2AuthenticationRequest をロードします。

デフォルトでは、Spring Security は HttpSessionSaml2AuthenticationRequestRepository を使用します。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 を介して自動的に構成することも、次のように手動で指定することもできます。

署名済み AuthnRequests は不要
  • 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();

それ以外の場合は、Spring Security が送信前に <saml2:AuthnRequest> に署名できるように、RelyingPartyRegistration#signingX509Credentials に秘密鍵を指定する必要があります。

デフォルトでは、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
}