4

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?

1 Answers1

11

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>
Vladimír Schäfer
  • 15,375
  • 2
  • 51
  • 71
  • Thanks for your answer. When I read the documentation from our IdP, it seems that sending the locale is done simply by adding the request parameter. Unfortunately the documentation is written in Norwegian, but it should be easy for you to find the example about locale: http://begrep.difi.no/ID-porten/SAMLAuthnRequest (Eksempel på overføring av locale) – Erlend Garåsen Mar 30 '15 at 08:23
  • You are right, that's what they seem to be using. I've updated the answer to cover customization allowing you to add such parameters. – Vladimír Schäfer Mar 30 '15 at 09:26
  • Thanks, this seems to work well. Since we need to change the language/locale settings dynamically, it would have been great to get access to either HttpServletRequest or Locale from the super class. – Erlend Garåsen Mar 30 '15 at 13:11
  • Thanks Vladi, it worked. I wonder if there is also a standard way to handle extra parameters sent by IDP (in the IDP initiated SSO). – Ritesh May 06 '15 at 07:56
  • @VladimírSchäfer, I have created the WebSSOProfile class in my project. But it doesn't seem to be invoked. I have put the debug points. Is there any settings I need to do? Some configurations or anything like that. I am using spring-saml2-core-1.0.2-RELEASE – Maz Jan 17 '19 at 19:45