You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Security SAML2如何在<Extensions>元素中传递语言代码

Spring Security SAML2 传递locale构造Extensions实现方案

Spring Security 核心版SAML2没有提供和旧扩展版SAMLMessageContext完全对等的组件,你可以通过请求上下文传递参数的方式实现EntryPoint到认证请求构造逻辑的参数传递,具体实现如下:


步骤1:自定义AuthenticationEntryPoint存储locale

你可以选择两种存储方式,按需选择:

  • 方式1:将locale作为参数附加到SAML认证发起跳转路径,实现简单
  • 方式2:将locale存入Session,避免参数暴露在URL中
public AuthenticationEntryPoint authenticationEntryPoint() {
    return (request, response, exception) -> {
        String locale = request.getParameter("locale");
        // 方式1:带参数跳转
        String redirectUrl = "/saml2/authenticate/sp?locale=" + URLEncoder.encode(locale, StandardCharsets.UTF_8);
        LoginUrlAuthenticationEntryPoint delegate = new LoginUrlAuthenticationEntryPoint(redirectUrl);
        
        // 方式2:存Session,跳转用原生路径
        // request.getSession().setAttribute("saml_request_locale", locale);
        // LoginUrlAuthenticationEntryPoint delegate = new LoginUrlAuthenticationEntryPoint("/saml2/authenticate/sp");
        
        delegate.commence(request, response, exception);
    };
}

步骤2:认证请求构造逻辑中读取locale

通过RequestContextHolder获取当前请求上下文,读取之前存储的locale参数即可:

@Bean
public Saml2AuthenticationRequestFactory authenticationRequestFactory() {
    final OpenSamlAuthenticationRequestFactory authenticationRequestFactory = new OpenSamlAuthenticationRequestFactory();
    authenticationRequestFactory.setAuthenticationRequestContextConverter(context -> {
        // 获取当前HttpServletRequest
        ServletRequestAttributes requestAttrs = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest currentRequest = requestAttrs.getRequest();
        
        // 对应方式1:读取URL参数
        String locale = currentRequest.getParameter("locale");
        
        // 对应方式2:读取Session属性,用完清除避免残留
        // String locale = (String) currentRequest.getSession().getAttribute("saml_request_locale");
        // currentRequest.getSession().removeAttribute("saml_request_locale");

        // 原有认证请求构造逻辑
        final AuthnRequest authnRequest = new AuthnRequestBuilder().buildObject();
        authnRequest.setAssertionConsumerServiceURL(context.getAssertionConsumerServiceUrl());
        authnRequest.setDestination(context.getDestination());
        authnRequest.setID("A" + UUID.randomUUID());
        authnRequest.setIssueInstant(new DateTime());
        final Issuer issuer = new IssuerBuilder().buildObject();
        issuer.setValue(context.getIssuer());
        authnRequest.setIssuer(issuer);
        
        // 用拿到的locale构造Extensions
        authnRequest.setExtensions(buildLanguageExtensions(locale));
        return authnRequest;
    });
    return authenticationRequestFactory;
}

注意事项

Spring Boot环境默认自动配置了RequestContextListener,可以直接使用RequestContextHolder获取请求上下文;如果是传统Spring项目,需要在web.xml中添加如下配置确保请求上下文可获取:

<listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>

内容的提问来源于stack exchange,提问作者KTJ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 14:54:05