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
相关产品推荐
相关产品推荐

