Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add request parameter to SAML request using Spring Security SAML

Tags:

spring-saml

I need to add a request parameter (e.g. locale=en) to the SAML request in order to let the login page display correct language. How do I do that?

I tried to add the attribute to the HttpServletRequest sent as an argument to the commence method (SamlEntryPoint), but that doesn't seem to work.

Any suggestions?

like image 240
Erlend Garåsen Avatar asked Dec 20 '22 05:12

Erlend Garåsen


1 Answers

SAML provides a standard mechanism for extending content sent in authentication requests - an Extensions element.

In order to use it you will need to coordinate with your IDP on what data you send and in what format. In Spring SAML you can customize its content by extending class WebSSOProfileImpl, for example like this:

package com.v7security.saml;

import org.opensaml.common.SAMLException;
import org.opensaml.saml2.common.Extensions;
import org.opensaml.saml2.common.impl.ExtensionsBuilder;
import org.opensaml.saml2.core.AuthnRequest;
import org.opensaml.saml2.metadata.AssertionConsumerService;
import org.opensaml.saml2.metadata.SingleSignOnService;
import org.opensaml.saml2.metadata.provider.MetadataProviderException;
import org.opensaml.xml.schema.XSAny;
import org.opensaml.xml.schema.impl.XSAnyBuilder;
import org.springframework.security.saml.context.SAMLMessageContext;
import org.springframework.security.saml.websso.WebSSOProfileImpl;
import org.springframework.security.saml.websso.WebSSOProfileOptions;

/**
 * Class adds additional extensions element to the AuthnRequest sent to IDP.
 */
public class WebSSOProfile extends WebSSOProfileImpl {

    @Override
    protected AuthnRequest getAuthnRequest(SAMLMessageContext context, WebSSOProfileOptions options, AssertionConsumerService assertionConsumer, SingleSignOnService bindingService) throws SAMLException, MetadataProviderException {
        AuthnRequest authnRequest = super.getAuthnRequest(context, options, assertionConsumer, bindingService);
        authnRequest.setExtensions(buildExtensions());
        return authnRequest;
    }

    protected Extensions buildExtensions() {

        XSAny languageClass = new XSAnyBuilder().buildObject("http://www.v7security.com/schema/2015/04/request", "RequestLanguage", "req");
        languageClass.setTextContent("urn:v7security:request:lang:english");

        Extensions extensions = new ExtensionsBuilder().buildObject();
        extensions.getUnknownXMLObjects().add(languageClass);
        return extensions;

    }

}

Another option is to send data in relayState, which is a piece of information SP can send to IDP and expect it to be bounced back (typically SP's state). The value is supposed to be opaque to the IDP, but of course it could process it for example in the way you intend. For details on setting the relay state see chapter on SP initialized SSO in the manual.

Setting request parameters on HttpRequest object is not expected to produce any result, Spring SAML doesn't automatically communicate these in any way.

It is possible to add an HTTP parameter to request sent with HTTP Redirect binding by extending class HTTPRedirectDeflateEncoder and overriding method buildRedirectURL. The new class can then be supplied into constructor of HTTPRedirectDeflateBinding and replaced in bean redirectBinding of securityContext.xml, in the following way:

<bean id="redirectBinding" class="org.springframework.security.saml.processor.HTTPRedirectDeflateBinding">
    <constructor-arg>
        <bean class="org.opensaml.saml2.binding.decoding.HTTPRedirectDeflateDecoder">
            <constructor-arg name="pool" ref="parserPool"/>
        </bean>
    </constructor-arg>
    <constructor-arg>
        <bean class="com.custom.HTTPRedirectDeflateEncoder"/>
    </constructor-arg>
</bean>
like image 113
Vladimír Schäfer Avatar answered Feb 02 '23 12:02

Vladimír Schäfer