# Producing `<saml2:AuthnRequest>`s

As stated earlier, Spring Security’s SAML 2.0 support produces a `<saml2:AuthnRequest>` 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 `<saml2:AuthnRequest>`.

## Changing How the `<saml2:AuthnRequest>` Gets Stored

`Saml2WebSsoAuthenticationRequestFilter` uses an `Saml2AuthenticationRequestRepository` to persist an `AbstractSaml2AuthenticationRequest` instance before [sending the `<saml2:AuthnRequest>`](#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 `<saml2:Response>`](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<AbstractSaml2AuthenticationRequest> authenticationRequestRepository() {
	return new CustomSaml2AuthenticationRequestRepository();
}
```

Kotlin

```
@Bean
open fun authenticationRequestRepository(): Saml2AuthenticationRequestRepository<AbstractSaml2AuthenticationRequest> {
    return CustomSaml2AuthenticationRequestRepository()
}
```

## Changing How the `<saml2:AuthnRequest>` Gets Sent

By default, Spring Security signs each `<saml2:AuthnRequest>` and send it as a GET to the asserting party.

Many asserting parties don’t require a signed `<saml2:AuthnRequest>`.
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 `<saml2:AuthnRequest>` before sending.

By default, Spring Security will sign the `<saml2:AuthnRequest>` 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<String?> ->
                    sign.add(
                        SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA512
                    )
                }
        }
        .build();
```

|   |The snippet above uses the OpenSAML `SignatureConstants` class to supply the algorithm name.<br/>But, that’s just for convenience.<br/>Since the datatype is `String`, you can supply the name of the algorithm directly.|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

Some asserting parties require that the `<saml2:AuthnRequest>` 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<Saml2AuthenticationRequestContext, AuthnRequest>` to build an `AuthnRequest` yourself, like so:

Java

```
@Component
public class AuthnRequestConverter implements
        Converter<Saml2AuthenticationRequestContext, AuthnRequest> {

    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<Saml2AuthenticationRequestContext, AuthnRequest> {
    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)