好的,过去几周我一直在研究 Spring Security,试图了解它们是如何组合在一起的。我仍在学习,但对于这种特殊情况,我发现了两种有效的方法。
最明显的就是绕过公共页面的安全性,如下所示:
@Override
public void configure(WebSecurity web) throws Exception
{
web
.ignoring()
.antMatchers("/", "/home", "/about", "/login**", "/thankyou", "/user/signup**", "/resources/**")
;
}
我对网络安全总体了解还不够,不知道这是否是可接受的方法,但它允许匿名用户浏览网站而不会出现无效会话错误。
更难的解决方案(对于像我这样的 Java 和 Spring 菜鸟来说)是基于这些 SO 问题:
Spring Security 无效会话重定向 https://stackoverflow.com/questions/30465618/spring-security-invalid-session-redirect
如何在 Spring Security 中设置自定义无效会话策略 https://stackoverflow.com/questions/25809367/how-to-set-a-custom-invalid-session-strategy-in-spring-security
默认SimpleRedirectInvalidSessionStrategy
类是final
这意味着我必须基本上创建该类的副本(不确定这是一个多好的想法)。您不能使用会话属性,因为会话在达到此策略时已被销毁,因此我为会话 cookie 创建了一个名为 authUser 的帮助程序类(如果有人想查看它,我可以发布该类)。 cookie 是在以下位置创建或更新的:LoginSuccessHandler
or RememberMeSuccessHandler
它指示用户是匿名还是经过身份验证:
authCookie.setCookie(request, response, "anonymousUser");
or
authCookie.setCookie(request, response, authentication.getName());
我目前仅将实际登录用于测试目的 - 它最终只是某种简单的是/否指示器。CustomLogoutSuccessHandler
将其重置为匿名用户
无效的会话方法如下所示:
@Override
public void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
String url = destinationUrl;
//reset context default value
redirectStrategy.setContextRelative(false);
if (authCookie.isCurrentCookieAnonymous()) {
//pass the URL originally requested by the anonymous user
url = request.getRequestURI();
//the URL needs to have the context removed
redirectStrategy.setContextRelative(true);
}
//always revert to anonymous user
authCookie.setCookie(request, response, "anonymousUser");
logger.debug("Starting new session (if required) and redirecting to '" + url + "'");
if (createNewSession)
request.getSession();
redirectStrategy.sendRedirect(request, response, url);
}
同样,如果需要,我可以发布完整的课程。
The SecurityConfig
类包括以下内容:
@Bean
public SessionManagementBeanPostProcessor sessionManagementBeanPostProcessor() {
return new SessionManagementBeanPostProcessor();
}
protected static class SessionManagementBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
if (bean instanceof SessionManagementFilter) {
SessionManagementFilter filter = (SessionManagementFilter) bean;
filter.setInvalidSessionStrategy(new RedirectInvalidSession("/errors/invalidSession"));
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
return bean;
}
}
到目前为止,我的测试对于匿名用户和经过身份验证的用户都是成功的,但这种方法尚未经过生产测试。