# Producing ``s As stated earlier, Spring Security’s SAML 2.0 support produces a `` to commence authentication with the asserting party. Spring Security achieves this in part by registering the `Saml2WebSsoAuthenticationRequestFilter` in the filter chain. This filter by default responds to endpoint `/saml2/authenticate/{registrationId}`. For example, if you were deployed to `[https://rp.example.com](https://rp.example.com)` and you gave your registration an ID of `okta`, you could navigate to: `[https://rp.example.org/saml2/authenticate/ping](https://rp.example.org/saml2/authenticate/ping)` and the result would be a redirect that included a `SAMLRequest` parameter containing the signed, deflated, and encoded ``. ## Changing How the `` Gets Stored `Saml2WebSsoAuthenticationRequestFilter` uses an `Saml2AuthenticationRequestRepository` to persist an `AbstractSaml2AuthenticationRequest` instance before [sending the ``](#servlet-saml2login-sp-initiated-factory) to the asserting party. Additionally, `Saml2WebSsoAuthenticationFilter` and `Saml2AuthenticationTokenConverter` use an `Saml2AuthenticationRequestRepository` to load any `AbstractSaml2AuthenticationRequest` as part of [authenticating the ``](authentication.html#servlet-saml2login-authenticate-responses). By default, Spring Security uses an `HttpSessionSaml2AuthenticationRequestRepository`, which stores the `AbstractSaml2AuthenticationRequest` in the `HttpSession`. If you have a custom implementation of `Saml2AuthenticationRequestRepository`, you may configure it by exposing it as a `@Bean` as shown in the following example: Java ``` @Bean Saml2AuthenticationRequestRepository authenticationRequestRepository() { return new CustomSaml2AuthenticationRequestRepository(); } ``` Kotlin ``` @Bean open fun authenticationRequestRepository(): Saml2AuthenticationRequestRepository { return CustomSaml2AuthenticationRequestRepository() } ``` ## Changing How the `` Gets Sent By default, Spring Security signs each `` and send it as a GET to the asserting party. Many asserting parties don’t require a signed ``. This can be configured automatically via `RelyingPartyRegistrations`, or you can supply it manually, like so: Example 1. Not Requiring Signed AuthnRequests Boot ``` spring: security: saml2: relyingparty: okta: identityprovider: entity-id: ... singlesignon.sign-request: false ``` Java ``` RelyingPartyRegistration relyingPartyRegistration = RelyingPartyRegistration.withRegistrationId("okta") // ... .assertingPartyDetails(party -> party // ... .wantAuthnRequestsSigned(false) ) .build(); ``` Kotlin ``` var relyingPartyRegistration: RelyingPartyRegistration = RelyingPartyRegistration.withRegistrationId("okta") // ... .assertingPartyDetails { party: AssertingPartyDetails.Builder -> party // ... .wantAuthnRequestsSigned(false) } .build(); ``` Otherwise, you will need to specify a private key to `RelyingPartyRegistration#signingX509Credentials` so that Spring Security can sign the `` before sending. By default, Spring Security will sign the `` using `rsa-sha256`, though some asserting parties will require a different algorithm, as indicated in their metadata. You can configure the algorithm based on the asserting party’s [metadata using `RelyingPartyRegistrations`](overview.html#servlet-saml2login-relyingpartyregistrationrepository). Or, you can provide it manually: Java ``` 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(); ``` Kotlin ``` var metadataLocation = "classpath:asserting-party-metadata.xml" var relyingPartyRegistration: RelyingPartyRegistration = RelyingPartyRegistrations.fromMetadataLocation(metadataLocation) // ... .assertingPartyDetails { party: AssertingPartyDetails.Builder -> party // ... .signingAlgorithms { sign: MutableList -> sign.add( SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA512 ) } } .build(); ``` | |The snippet above uses the OpenSAML `SignatureConstants` class to supply the algorithm name.
But, that’s just for convenience.
Since the datatype is `String`, you can supply the name of the algorithm directly.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| Some asserting parties require that the `` be POSTed. This can be configured automatically via `RelyingPartyRegistrations`, or you can supply it manually, like so: Java ``` RelyingPartyRegistration relyingPartyRegistration = RelyingPartyRegistration.withRegistrationId("okta") // ... .assertingPartyDetails(party -> party // ... .singleSignOnServiceBinding(Saml2MessageBinding.POST) ) .build(); ``` Kotlin ``` var relyingPartyRegistration: RelyingPartyRegistration? = RelyingPartyRegistration.withRegistrationId("okta") // ... .assertingPartyDetails { party: AssertingPartyDetails.Builder -> party // ... .singleSignOnServiceBinding(Saml2MessageBinding.POST) } .build() ``` ## Customizing OpenSAML’s `AuthnRequest` Instance There are a number of reasons that you may want to adjust an `AuthnRequest`. For example, you may want `ForceAuthN` to be set to `true`, which Spring Security sets to `false` by default. If you don’t need information from the `HttpServletRequest` to make your decision, then the easiest way is to [register a custom `AuthnRequestMarshaller` with OpenSAML](overview.html#servlet-saml2login-opensaml-customization). This will give you access to post-process the `AuthnRequest` instance before it’s serialized. But, if you do need something from the request, then you can use create a custom `Saml2AuthenticationRequestContext` implementation and then a `Converter` to build an `AuthnRequest` yourself, like so: Java ``` @Component public class AuthnRequestConverter implements Converter { private final AuthnRequestBuilder authnRequestBuilder; private final IssuerBuilder issuerBuilder; // ... constructor public AuthnRequest convert(Saml2AuthenticationRequestContext context) { MySaml2AuthenticationRequestContext myContext = (MySaml2AuthenticationRequestContext) context; Issuer issuer = issuerBuilder.buildObject(); issuer.setValue(myContext.getIssuer()); AuthnRequest authnRequest = authnRequestBuilder.buildObject(); authnRequest.setIssuer(issuer); authnRequest.setDestination(myContext.getDestination()); authnRequest.setAssertionConsumerServiceURL(myContext.getAssertionConsumerServiceUrl()); // ... additional settings authRequest.setForceAuthn(myContext.getForceAuthn()); return authnRequest; } } ``` Kotlin ``` @Component class AuthnRequestConverter : Converter { private val authnRequestBuilder: AuthnRequestBuilder? = null private val issuerBuilder: IssuerBuilder? = null // ... constructor override fun convert(context: Saml2AuthenticationRequestContext): AuthnRequest { val myContext: MySaml2AuthenticationRequestContext = context val issuer: Issuer = issuerBuilder.buildObject() issuer.value = myContext.getIssuer() val authnRequest: AuthnRequest = authnRequestBuilder.buildObject() authnRequest.issuer = issuer authnRequest.destination = myContext.getDestination() authnRequest.assertionConsumerServiceURL = myContext.getAssertionConsumerServiceUrl() // ... additional settings authRequest.setForceAuthn(myContext.getForceAuthn()) return authnRequest } } ``` Then, you can construct your own `Saml2AuthenticationRequestContextResolver` and `Saml2AuthenticationRequestFactory` and publish them as `@Bean`s: Java ``` @Bean Saml2AuthenticationRequestContextResolver authenticationRequestContextResolver() { Saml2AuthenticationRequestContextResolver resolver = new DefaultSaml2AuthenticationRequestContextResolver(); return request -> { Saml2AuthenticationRequestContext context = resolver.resolve(request); return new MySaml2AuthenticationRequestContext(context, request.getParameter("force") != null); }; } @Bean Saml2AuthenticationRequestFactory authenticationRequestFactory( AuthnRequestConverter authnRequestConverter) { OpenSaml4AuthenticationRequestFactory authenticationRequestFactory = new OpenSaml4AuthenticationRequestFactory(); authenticationRequestFactory.setAuthenticationRequestContextConverter(authnRequestConverter); return authenticationRequestFactory; } ``` Kotlin ``` @Bean open fun authenticationRequestContextResolver(): Saml2AuthenticationRequestContextResolver { val resolver: Saml2AuthenticationRequestContextResolver = DefaultSaml2AuthenticationRequestContextResolver() return Saml2AuthenticationRequestContextResolver { request: HttpServletRequest -> val context = resolver.resolve(request) MySaml2AuthenticationRequestContext( context, request.getParameter("force") != null ) } } @Bean open fun authenticationRequestFactory( authnRequestConverter: AuthnRequestConverter? ): Saml2AuthenticationRequestFactory? { val authenticationRequestFactory = OpenSaml4AuthenticationRequestFactory() authenticationRequestFactory.setAuthenticationRequestContextConverter(authnRequestConverter) return authenticationRequestFactory } ``` [SAML2 Log In Overview](overview.html)[SAML2 Authentication Responses](authentication.html)