Internationalization 如何在spring安全登录页面中启用LocaleInterceptor来更改区域设置?

Internationalization 如何在spring安全登录页面中启用LocaleInterceptor来更改区域设置?,internationalization,spring-security,locale,Internationalization,Spring Security,Locale,请原谅,如果以前有人问过这个问题,我还没有得到一个直接的答案来帮助我解决问题。 我有一个gwt应用程序,我已经使用spring安全性进行了保护。Spring security只是对用户进行身份验证并重定向到gwt应用程序。现在,我希望用户能够从登录页面上的链接更改区域设置,然后将区域设置存储在cookie中并在应用程序中使用 在applicationContext.xml中,我有以下配置 <http auto-config="true"> <intercept-url

请原谅,如果以前有人问过这个问题,我还没有得到一个直接的答案来帮助我解决问题。 我有一个gwt应用程序,我已经使用spring安全性进行了保护。Spring security只是对用户进行身份验证并重定向到gwt应用程序。现在,我希望用户能够从登录页面上的链接更改区域设置,然后将区域设置存储在cookie中并在应用程序中使用

在applicationContext.xml中,我有以下配置

<http auto-config="true">
    <intercept-url pattern="/mywebapp/**" access="ROLE_USER"/>
    <intercept-url pattern="/gwt/**" access="ROLE_USER"/>
    <intercept-url pattern="/**/*.html" access="ROLE_USER"/>
    <intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    <intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <form-login login-page="/login.jsp"/>
</http>
<beans:bean id="userDetailsService"
    class="com.kibet.mywebapp.server.auth.UserDetailsServiceImpl">
</beans:bean>

...
<!-- Application Message Bundle -->
<beans:bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <beans:property name="basename" value="classpath:messages" />
    <beans:property name="defaultEncoding" value="UTF-8"/>
</beans:bean>

<beans:bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
    <beans:property name="paramName" value="lang" />
</beans:bean>

<beans:bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
    <beans:property name="defaultLocale" value="pt"/>
</beans:bean>

<beans:bean id="urlMapping"
     class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <beans:property name="interceptors">
    <beans:list>
        <beans:ref bean="localeChangeInterceptor"/>
    </beans:list>
    </beans:property>
    <beans:property name="mappings">
    <beans:value>/login.jsp=userDetailsService</beans:value>
    </beans:property>
</beans:bean>

LocaleChangeInterceptor
是SpringMVC的一部分,这意味着它们不会出现在SpringSecurity过滤器中。您必须自己在过滤器链中设置语言环境。另请参见

感谢@Ritesh给出答案。 你给我一个解决这个问题的办法。 我用了一种更进一步的方法来解决这个问题:

public class InternationalizationFilter extends OncePerRequestFilter {
  private Logger log=Logger.getLogger(InternationalizationFilter.class);
  private String localeParam="lang";
  private LocaleResolver localeResolver;

  public InternationalizationFilter(String localeParam, LocaleResolver localeResolver) {
    this.localeParam = localeParam;
    this.localeResolver = localeResolver;
  }

  @Override
  public void destroy() {
    // TODO Auto-generated method stub

  }

  @Override
  protected void doFilterInternal(
      final HttpServletRequest request,
      final HttpServletResponse response,
      final FilterChain filterChain)
      throws ServletException, IOException {
    if (localeResolver == null) {
      throw new IllegalStateException("No LocaleResolver found: not in a DispatcherServlet request?");
    }
    else{
      final String newLocale = request.getParameter(localeParam);
      if (newLocale != null) {
        final Locale locale = StringUtils.parseLocaleString(newLocale.toLowerCase());
        LocaleContextHolder.setLocale(locale);
        LocaleEditor localeEditor = new LocaleEditor();
        localeEditor.setAsText(newLocale);
        localeResolver.setLocale(request, response, (Locale) localeEditor.getValue());
        log.debug("change locale to "+
            locale.getLanguage()+"_"+locale.getCountry()+
            " at Thread"+Thread.currentThread().getId());
      }
      else{
        final Locale locale=localeResolver.resolveLocale(request);
        LocaleContextHolder.setLocale(locale);
        log.debug("restore locale to "+
            locale.getLanguage()+"_"+locale.getCountry()+
            " at Thread"+Thread.currentThread().getId());
      }
      try {
        filterChain.doFilter(request, response);
      } finally {
        LocaleContextHolder.resetLocaleContext();
      }
    }
  }

}
在mvc配置文件中声明了localChangeInterceptor和localeResolver。 因此,我们可以使用请求参数“lang”更改区域设置:


在安全配置文件中,我制作了一个i18nFilter并将其添加到过滤器链中:

  <bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
    <security:filter-chain-map path-type="ant">
      <security:filter-chain pattern="/**/*.css" filters="
          securityContextPersistenceFilter,
          exceptionTranslationFilter"/>
      <security:filter-chain pattern="/**/*.jpg" filters="
          securityContextPersistenceFilter,
          exceptionTranslationFilter"/>
      <security:filter-chain pattern="/**/*.png" filters="
          securityContextPersistenceFilter,
          exceptionTranslationFilter"/>
      <security:filter-chain pattern="/**/*.gif" filters="
          securityContextPersistenceFilter,
          exceptionTranslationFilter"/>
      <security:filter-chain pattern="/**/*.js" filters="
          securityContextPersistenceFilter,
          exceptionTranslationFilter"/>
      <security:filter-chain pattern="/**/*.cur" filters="
          securityContextPersistenceFilter,
          exceptionTranslationFilter"/>
      <security:filter-chain pattern="/**/*.swf" filters="
          securityContextPersistenceFilter,
          exceptionTranslationFilter"/>
      <security:filter-chain pattern="/login" filters="
          i18nFilter,
          securityContextPersistenceFilter,
          exceptionTranslationFilter"/>
      <security:filter-chain pattern="/checkin" filters="
          i18nFilter,
          securityContextPersistenceFilter,
          authenticationFilter"/>
      <security:filter-chain pattern="/**" filters="
           i18nFilter,
           securityContextPersistenceFilter,
           authenticationFilter,
           logoutFilter,
           anonymousAuthenticationFilter,
           exceptionTranslationFilter,
           filterSecurityInterceptor" />

    </security:filter-chain-map>
  </bean> 



<bean id="i18nFilter" class="com.bjinfotech.filter.InternationalizationFilter">
    <constructor-arg name="localeParam" value="lang"/>
    <constructor-arg name="localeResolver" ref="localeResolver"/>
  </bean>

使用localChangeInterceptor和localeResolver,我可以更改语言环境并将语言环境保存到会话或cookie中

在localeResolver的帮助下,InternationalizationFilter可以存储/还原区域设置并更改LocaleContextHolder的区域设置。

首先,键是,忘记拦截器

只需创建一个实现此接口的bean,以解析保存它的区域设置,例如请求的属性

public class LocaleResolverImpl implements LocaleResolver {

    public LocaleResolverImpl() {
    }

    @Override
    public Locale resolveLocale(HttpServletRequest request) {
        Locale r = (Locale) request.getAttribute("localeObject");
        return r == null ? request.getLocale() : r;
    }

    @Override
    public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}

谢谢@Ritesh,你说得对,LocaleChangeInterceptor不是SpringSecurity的一部分。不幸的是,与SpringSecurity捆绑在一起的示例应用程序没有提供太多帮助。因此,我已经实现了一个自定义过滤器,专门在表单\登录\过滤器之前设置过滤器链中的区域设置。当我运行应用程序时,我可以看到过滤器在UsernamePasswordAuthenticationFilter之前注册,但当我尝试更改区域设置时,它不起作用。这是我的自定义过滤器配置
@kibyegn请在问题中添加国际化过滤器的代码。好的。您在web.xml中有org.springframework.web.filter.RequestContextFilter吗?这个答案没有给出完整的图片。。。在您的情况下,当您让Spring安全性直接转发到JSP时,Spring MVC不会生效。然而,更常见的是转发到SpringMVC(一些
LoginController
),以便登录本身通过SpringMVC呈现。不需要定制过滤器。我认为downvote很苛刻。任何答案都应根据其解决的问题进行评估。这里,问题的关键语句是“[T]登录页面由spring security生成,处理程序映射无法拦截区域设置更改请求”。我认为在某些情况下需要在过滤链中设置语言环境。哇。。。杂乱无章,没有必要。你能再解释一下吗?我无法将您的解决方案映射到我的代码。我正在跟踪此链接。我想更改登录页面上的区域设置。蒂亚。
  <bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
    <security:filter-chain-map path-type="ant">
      <security:filter-chain pattern="/**/*.css" filters="
          securityContextPersistenceFilter,
          exceptionTranslationFilter"/>
      <security:filter-chain pattern="/**/*.jpg" filters="
          securityContextPersistenceFilter,
          exceptionTranslationFilter"/>
      <security:filter-chain pattern="/**/*.png" filters="
          securityContextPersistenceFilter,
          exceptionTranslationFilter"/>
      <security:filter-chain pattern="/**/*.gif" filters="
          securityContextPersistenceFilter,
          exceptionTranslationFilter"/>
      <security:filter-chain pattern="/**/*.js" filters="
          securityContextPersistenceFilter,
          exceptionTranslationFilter"/>
      <security:filter-chain pattern="/**/*.cur" filters="
          securityContextPersistenceFilter,
          exceptionTranslationFilter"/>
      <security:filter-chain pattern="/**/*.swf" filters="
          securityContextPersistenceFilter,
          exceptionTranslationFilter"/>
      <security:filter-chain pattern="/login" filters="
          i18nFilter,
          securityContextPersistenceFilter,
          exceptionTranslationFilter"/>
      <security:filter-chain pattern="/checkin" filters="
          i18nFilter,
          securityContextPersistenceFilter,
          authenticationFilter"/>
      <security:filter-chain pattern="/**" filters="
           i18nFilter,
           securityContextPersistenceFilter,
           authenticationFilter,
           logoutFilter,
           anonymousAuthenticationFilter,
           exceptionTranslationFilter,
           filterSecurityInterceptor" />

    </security:filter-chain-map>
  </bean> 



<bean id="i18nFilter" class="com.bjinfotech.filter.InternationalizationFilter">
    <constructor-arg name="localeParam" value="lang"/>
    <constructor-arg name="localeResolver" ref="localeResolver"/>
  </bean>
public class LocaleResolverImpl implements LocaleResolver {

    public LocaleResolverImpl() {
    }

    @Override
    public Locale resolveLocale(HttpServletRequest request) {
        Locale r = (Locale) request.getAttribute("localeObject");
        return r == null ? request.getLocale() : r;
    }

    @Override
    public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}