使用 Spring 安全 SAML 将请求参数添加到 SAML 请求

Add request parameter to SAML request using Spring Security SAML

我需要在 SAML 请求中添加一个请求参数(例如 locale=en),以便让登录页面显示正确的语言。我该怎么做?

我试图将属性添加到作为参数发送到开始方法 (SamlEntryPoint) 的 HttpServletRequest,但这似乎不起作用。

有什么建议吗?

SAML 提供了一种标准机制来扩展身份验证请求中发送的内容 - Extensions 元素。

为了使用它,您需要与您的 IDP 就您发送的数据和格式进行协调。在 Spring SAML 中,您可以通过扩展 class WebSSOProfileImpl 来自定义其内容,例如:

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;

    }

}

另一种选择是在 relayState 中发送数据,这是 SP 可以发送给 IDP 并期望它被退回的一条信息(通常是 SP 的状态)。该值应该对 IDP 不透明,但当然它可以按照您想要的方式处理它。有关设置继电器状态的详细信息,请参阅 chapter on SP initialized SSO in the manual

HttpRequest 对象上设置请求参数预计不会产生任何结果,Spring SAML 不会以任何方式自动传达这些。

可以通过扩展 class HTTPRedirectDeflateEncoder 和覆盖方法 buildRedirectURL 向使用 HTTP 重定向绑定发送的请求添加 HTTP 参数。然后可以将新的 class 提供给 HTTPRedirectDeflateBinding 的构造函数并替换为 securityContext.xml 的 bean redirectBinding,方法如下:

<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>