Skip to content

Add Saml2AuthenticationRequestResolver #10355

Closed
@jzheaux

Description

@jzheaux

Similar to OAuth2AuthenticationRequestResolver, Saml2AuthenticationRequestResolver would be a convenient way to customize the AuthnRequest based on inputs from the request as well as the RelyingPartyRegistration.

The OpenSAML implementation would have a method setAuthnRequestCustomizer similar to OAuth2AuthenticationRequestResolver#setAuthenticationRequestCustomizer. This method would overcome a limitation in OpenSamlAuthenticationRequestFactory's equivalent method setAuthenticationRequestContextConverter, which is that it does not have access to the HttpServletRequest.

This component would supercede Saml2AuthenticationRequestContextResolver, Saml2AuthenticationRequestContext, and Saml2AuthenticationRequestFactory reducing configuration like:

public class MySaml2AuthenticationRequestContext extends Saml2AuthenticationRequestContext {
    boolean force;

    public MySaml2AuthenticationRequestContext(Saml2AuthenticationRequestContext parent, boolean force) {
        super(parent.getRelyingPartyRegistration(), parent.getIssuer(), 
                parent.getAssertionConsumerServiceUrl(), parent.getRelayState());
        this.force = force;
    }

    public boolean isForce() {
        return this.force;
    }
}

// ...

@Component
public class AuthnRequestConverter implements
        Converter<MySaml2AuthenticationRequestContext, 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;
    }
}

// ...

@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;
}

to

@Bean
Saml2AuthenticationRequestResolver authenticationRequestResolver(
        RelyingPartyRegistrationResolver registrations) {
    OpenSamlAuthenticationRequestResolver resolver = new OpenSamlAuthenticationRequestResolver(registrations);
    resolver.setAuthnRequestCustomizer((tuple) -> {
        HttpServletRequest request = tuple.getRequest();
        AuthnRequest authnRequest = tuple.getAuthnRequest();
        authnRequest.setForceAuthn(request.getParameter("force") != null);
    });
}

It would also bring the SAML 2.0 support into closer alignment with the OAuth 2.0 support.

Using Saml2AuthenticationRequestContextResolver, Saml2AuthenticationRequestContext, and Saml2AuthenticationRequestFactory will still continue to work and be supported, though moving to Saml2AuthenticationRequestResolver would be encouraged.

A related discussion about motives can be found starting at #8141 (comment). This would also obviate the need for #9209 and would close #9199.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions