使用Spring Security控制会话的方法
1.概述
在本文中,我们将说明SpringSecurity如何允许我们控制HTTP会话。此控件的范围从会话超时到启用并发会话和其他高级安全配置。
2.会话何时创建?
我们可以准确控制会话何时创建以及SpringSecurity如何与之交互:
•always-如果一个会话尚不存在,将始终创建一个会话
•ifRequired-仅在需要时创建会话(默认)
•never-框架永远不会创建会话本身,但如果它已经存在,它将使用一个
•stateless-SpringSecurity不会创建或使用任何会话
Java配置:
@Override protectedvoidconfigure(HttpSecurityhttp)throwsException{ http.sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) }
了解此配置仅控制SpringSecurity的功能非常重要-而不是整个应用程序。如果我们不指示SpringSecurity,可能无法创建会话,但我们的应用程序可能会!
默认情况下,SpringSecurity会在需要时创建会话-这是“ifRequired”。
对于更无状态的应用程序,“never”选项将确保SpringSecurity本身不会创建任何会话;但是,如果应用程序创建了一个,那么SpringSecurity将使用它。
最后,最严格的会话创建选项-“stateless”-保证应用程序根本不会创建任何会话。
这是在Spring3.1中引入的,它将有效地跳过部分SpringSecurity过滤器链。主要是会话相关的部分,如
HttpSessionSecurityContextRepository,SessionManagementFilter,RequestCacheFilter。
这些更严格的控制机制直接暗示不使用cookie,所以每个请求都需要重新进行身份验证。这种无状态架构适用于RESTAPI及其无状态约束。它们也适用于基本和摘要式身份验证等身份验证机制。
3.UnderTheHood
在执行身份验证过程之前,SpringSecurity将运行一个负责在请求之间存储安全上下文的过滤器-SecurityContextPersistenceFilter。上下文将根据策略存储-默认情况下为HttpSessionSecurityContextRepository-它使用HTTP会话作为存储。对于strictcreate-session=“stateless”属性,此策略将替换为另一个-NullSecurityContextRepository-并且不会创建或使用会话来保留上下文。
4.并发会话控制
当已经过身份验证的用户尝试再次进行身份验证时,应用程序可以通过以下几种方式之一处理该事件。它可以使用户的活动会话无效,并使用新会话再次对用户进行身份验证,或者允许两个会话同时存在。
启用并发会话控制支持的第一步是在web.xml中添加以下侦听器:
org.springframework.security.web.session.HttpSessionEventPublisher
或者将其定义为Bean-如下所示:
@Bean publicHttpSessionEventPublisherhttpSessionEventPublisher(){ returnnewHttpSessionEventPublisher(); }
这对于确保在销毁会话时通知SpringSecurity会话注册表是至关重要。
要为同一用户启用允许多个并发会话的方案,应在XML配置中使用元素:
或者,通过Java配置:
@Override protectedvoidconfigure(HttpSecurityhttp)throwsException{ http.sessionManagement().maximumSessions(2) }
5.会话超时
会话超时后,如果用户发送的会话ID已过期,则会将其重定向到可通过命名空间配置的URL:
同样,如果用户发送的会话ID未过期但完全无效,则它们也会被重定向到可配置的URL:
...
相应的Java配置:
http.sessionManagement() .expiredUrl("/sessionExpired.html") .invalidSessionUrl("/invalidSession.html");
6.防止使用URL参数进行会话跟踪
在URL中公开会话信息的安全风险越来越大(从2007年的第7位到2013年在OWASP排行榜前10位的第2位)。
从Spring3.0开始,现在可以通过在命名空间中设置disable-url-rewriting=“true”来禁用将jsessionid附加到URL的URL重写逻辑。
或者,从Servlet3.0开始,也可以在web.xml中配置会话跟踪机制:
COOKIE
编程方式
servletContext.setSessionTrackingModes(EnumSet.of(SessionTrackingMode.COOKIE));
这将选择存储JSESSIONID的位置-在cookie或URL参数中。
7.SpringSecurity的会话固定保护
该框架通过配置在用户已有会话的情况但尝试再次进行身份验证时,提供了针对典型会话固定攻击的保护:
相应的Java配置:
http.sessionManagement() .sessionFixation().migrateSession()
默认情况下,SpringSecurity启用了此保护(“migrateSession”)-在身份验证时,会创建一个新的HTTP会话,旧的会话将失效,旧会话的属性将被复制。
如果这不是所需的行为,则可以使用其他两个选项:
•设置“none”时,原始会话不会失效
•设置“newSession”时,将创建一个干净的会话,而不会复制旧会话中的任何属性
8.安全会话Cookie
接下来,我们将讨论如何保护会话cookie。
我们可以使用httpOnly和secure标签来保护我们的会话cookie:
•httpOnly:如果为true,那么浏览器脚本将无法访问cookie
•secure:如果为true,则cookie将仅通过HTTPS连接发送
我们可以在web.xml中为会话cookie设置这些标志:
1 true true
从Javaservlet3开始,此配置选项可用。默认情况下,http-only为true且secure为false。
我们来看看相应的Java配置:
publicclassMainWebAppInitializerimplementsWebApplicationInitializer{ @Override publicvoidonStartup(ServletContextsc)throwsServletException{ //... sc.getSessionCookieConfig().setHttpOnly(true); sc.getSessionCookieConfig().setSecure(true); } }
如果我们使用SpringBoot,我们可以在application.properties中设置这些标志:
server.servlet.session.cookie.http-only=true server.servlet.session.cookie.secure=true
最后,我们还可以使用Filter手动实现此目的:
publicclassSessionFilterimplementsFilter{ @Override publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain) throwsIOException,ServletException{ HttpServletRequestreq=(HttpServletRequest)request; HttpServletResponseres=(HttpServletResponse)response; Cookie[]allCookies=req.getCookies(); if(allCookies!=null){ Cookiesession= Arrays.stream(allCookies).filter(x->x.getName().equals("JSESSIONID")) .findFirst().orElse(null); if(session!=null){ session.setHttpOnly(true); session.setSecure(true); res.addCookie(session); } } chain.doFilter(req,res); } }
9.Session使用
9.1。SessionScopedBeans
只需在web-Context中,使用@Scope注释声明的bean:
@Component @Scope("session") publicclassFoo{..}
或者使用XML:
然后,bean可以简单地注入另一个bean:
@Autowired privateFootheFoo;
Spring会将新bean绑定到HTTPSession的生命周期。
9.2。将会话注入控制器
原始HTTP会话也可以直接注入Controller方法:
@RequestMapping(..) publicvoidfooMethod(HttpSessionsession){ session.addAttribute(Constants.FOO,newFoo(); //... Foofoo=(Foo)session.getAttribute(Constants.Foo); }
9.3。获取会话
当前的HTTPSession也可以通过原始ServletAPI以编程方式获得:
ServletRequestAttributesattr=(ServletRequestAttributes) RequestContextHolder.currentRequestAttributes(); HttpSessionsession=attr.getRequest().getSession(true);//true==allowcreate
10.总结
在本文中,我们讨论了使用SpringSecurity管理Sessions。此外,SpringReference包含一个非常好的会话管理常见问题解答。
与往常一样,本文中提供的代码可以在Github上获得。这是一个基于Maven的项目,因此它应该很容易导入和运行。
以上所述是小编给大家介绍的使用SpringSecurity控制会话的方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。