Как включить LocaleInterceptor для изменения локали на странице входа в Spring-Security? - PullRequest
6 голосов
/ 09 марта 2011

Извините, если этот вопрос задавался ранее, но я не получил прямого ответа, который помог бы мне решить мою проблему.У меня есть приложение gwt, которое я защитил с помощью Spring-Security.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>

Это не похоже на работу.У меня есть файлы свойств локали messages_en.properties, messages_es.properties и messages_pt.properties в моем classpath.Единственный раз, когда это работает, это когда я меняю локаль браузера по умолчанию.Насколько я могу судить, страница входа в систему генерируется Spring-Security, и отображение обработчика не может перехватить запрос на изменение локали.Если это причина, как бы я пошел по этому поводу?Помощь высоко ценится.

Вот мой пользовательский код фильтра.

public class InternationalizationFilter implements Filter {

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

}

@Override
public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain filterChain) throws IOException, ServletException {
    String newLocale = request.getParameter("lang");
    if (newLocale != null) {
        Locale locale = StringUtils.parseLocaleString(newLocale
                .toLowerCase());
        LocaleContextHolder.setLocale(locale);
    }
    try {
        filterChain.doFilter(request, response);
    } finally {

        LocaleContextHolder.resetLocaleContext();
    }
}

@Override
public void init(FilterConfig arg0) throws ServletException {

}}

Ответы [ 3 ]

4 голосов
/ 23 декабря 2011

Спасибо @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();
      }
    }
  }

}

С объявленными localChangeInterceptor и localeResolver в конфигурационном файле mvc.Таким образом, мы можем изменить локаль с параметром запроса «lang»:

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


  <!--localeResolver-->
  <bean id="localeResolver"
        class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
    <!--<property name="cookieDomain" value=""/>-->
    <property name="defaultLocale" value="zh"/>
  </bean>

В файле конфигурации безопасности я создал 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.

1 голос
/ 28 марта 2016

Сначала ключ 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.");
    }
}
1 голос
/ 09 марта 2011

LocaleChangeInterceptor является частью Spring MVC, и это означает, что они не отображаются в фильтрах безопасности Spring. Вы должны будете установить локаль внутри цепочки фильтров. Также см. Spring Security / SEC-1527: Интернационализация одного из примеров приложений

...