我使用的是Spring Security 3.0.2,我有这个配置
<security:form-login
login-processing-url="/resources/j_spring_security_check"
login-page="/login"
authentication-failure-handler-ref="authErrorHandler" authentication-success-handler-ref="authCorrectHandler" />
<security:logout logout-success-url="/index.jsp" invalidate-session="false" />
<security:remember-me />
<security:session-management invalid-session-url="/login/sessionExpired" >
<security:concurrency-control max-sessions="1"
error-if-maximum-exceeded="true" />
</security:session-management>
当我使用某个区域设置登录时,一切顺利,但是当会话到期时,Spring Security会清除会话并默认使用区域设置创建新的匿名会话(并按预期转到登录页面)。结果是用户区域设置为LOST。
如何在Spring Security 3.0.2中使会话到期时保留用户区域设置?
我使用localeChangeInterceptor设置语言环境,如下所示:
<bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="language" />
</bean>
和SessionLocaleResolver作为区域设置解析器:
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
<property name="defaultLocale" value="es" />
</bean>
我终于在我自己的 LocaleChangeInterceptor 中设置了一个 cookie ,它从 HandlerInterceptorAdapter 扩展,在中写下来preHandle 方法:
LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
if (localeResolver == null) {
throw new IllegalStateException("No LocaleResolver found.");
}
Cookie mylang = new Cookie("mylang", locale.getLanguage() + "_" + locale.getCountry());
mylang.setMaxAge(86400);
response.addCookie(mylang);
localeResolver.setLocale(request, response, locale);
然后在 / sessionExpired 控制器点,我获得了Cookie值:
public String sessionExpired(HttpServletRequest request, HttpServletResponse response, Model model,
@CookieValue(value = "mylang", defaultValue = "es_ES") String myLang) throws Exception {
model.addAttribute("mylang", myLang);
LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
StringTokenizer st = new StringTokenizer(myLang, "_");
String language = "";
String country = "";
try {
language = (String) st.nextElement();
country = (String) st.nextElement();
} catch (Exception e) {
throw new Exception("Error locale");
}
Locale locale = new Locale(language, country);
localeResolver.setLocale(request, response, locale);
return "sessionExpired";
在这种情况下,无需使用数据库作为临时存储。
答案 0 :(得分:2)
从逻辑上讲,您似乎无法使用会话来跟踪区域设置。使用请求参数language
设置区域设置,该参数将通过会话清除。创建新会话时,区域设置默认为es
给出的localeResolver
。我可以想到的一种方法是将用户首选项存储在数据库中,并在后续登录时从那里检索
同样由@M建议。 Deinum:
如果你对cookie没问题,可以使用CookieLocaleResolver
来保留cookie中的选择。否则,实现自己的LocaleResolver
存储/从数据库检索。