首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

《Spring Security3》第六章第三一部分翻译(Session的管理和并发)

2012-10-18 
《Spring Security3》第六章第三部分翻译(Session的管理和并发)Session的管理和并发Spring Security的一个常

《Spring Security3》第六章第三部分翻译(Session的管理和并发)
Session的管理和并发

Spring Security的一个常见配置就是检测相同的用户以不同的session登录安全系统。这被称为并发控制(concurrency control,是session管理(session management一系列相关配置功能的一部分。严格来说,这个功能并不是高级配置,但是它会让很多新手感到迷惑,并且最好在你对Sping Security整体功能有所了解的基础上再掌握它。Spring Security的session管理能够以两种不同的方式进行配置——session固化保护(session fixation protection)和并发控制。因为并发控制的功能基于session固化保护所提供的框架,我们先介绍session固化。

配置session fixation防护

<http auto-config="true" use-expressions="true"> <!-- ... --> <session-management session-fixation-protection="migrateSession"/></http>

?Session固化防护这个功能你可能并不会在意,除非你想扮演一个恶意的用户。我们将向你展示如何模拟一个session窃取攻击,但是在此之前,有必要理解session固化是怎么回事以及怎样防止这样的攻击。

理解session fixation攻击

下图展现了session固化攻击是如何发生的:


《Spring Security3》第六章第三一部分翻译(Session的管理和并发)
?既然了解了攻击如何进行,接下来我们查看SpringSecurity如何防止。

使用Spring Security防止session fixation攻击

如果我们能够阻止用户在认证前和认证后使用相同的session,我们就能够让攻击者掌握的session ID信息变得没有用处。Spring Security的session固化防护解决这个问题的方式就是在用户认证之后明确创建一个新的session并将旧的session失效。

让我们看下图:


《Spring Security3》第六章第三一部分翻译(Session的管理和并发)
?我们可以看到一个新的过滤器,o.s.s.web.session.SessionManagementFilter,负责检查一个特定的用户是否为新认证的。如果用户是新认证的,一个配置的o.s.s.web.authentication.session.SessionAuthenticationStrategy将确定要怎样做。o.s.s.web.authentication.session.SessionAuthenticationStrategy将会创建一个新的session(如果用户已经拥有一个的话),并将已存在session的内容拷贝到新session中去。这看起来很简单,但是,通过上面的图表我们可以看到,它能够有效组织恶意用户在未知用户登录后重用session ID。

模拟session fixation攻击

此时,你可能会想要看一下在模拟session固化攻击时会涉及到什么。为了实现这一点,你需要在dogstore-security.xml中配置session固化防护失效。

?

<session-management session-fixation-protection="none"/>

?? ? ? ??在IE中打开JBCP Pets首页,然后打开开发者工具(看“工具”下拉菜单或点击F12),并在“缓存”菜单下选择“查看Cookie信息”。在合适域下(如果使用localhost将为空)找到JSESSIONID的cookie。


《Spring Security3》第六章第三一部分翻译(Session的管理和并发)

????????? 将sessioncookie的值复制到粘贴板上,然后登录JBCP Pets站点。如果你重复“查看Cookie信息”,你将会发现JSESSIONID在登录后没有变化,这将会导致很容易受到session固化攻击。

?? ? ? ??在Firefox下,打开JBCP Pets站点。你将会被分配一个sessioncookie,这能通过Cookie菜单的“查看Cookie信息”菜单项查看到。

?


《Spring Security3》第六章第三一部分翻译(Session的管理和并发)
?为了完成我们的攻击,我们点击“EditCookie”选项,并将从IE中复制到粘贴板上的JSESSIONID值粘贴进来,如下图所示:


《Spring Security3》第六章第三一部分翻译(Session的管理和并发)
?我们的session固化攻击完成了!如果此时在Firefox中重新加载页面,你将以IE中已登录用户相同的身份进入系统,并不需要你知道用户名和密码。你是否害怕恶意用户了?

现在,重新使session固化防护生效然后重新尝试这个练习。你会发现,在这种情况下,JSESSIONID在用户登录后会发生变化。因为你已经了解了session固化攻击是如何发生的,这意味着减少了可信任用户陷入这种攻击的风险。干的漂亮!

细心的开发人员应该会注意到有很多种窃取sessioncookie的方式,有一些如跨站脚本攻击(XSS)可能会使得session固化防护都很脆弱。请访问OWASP站点来了解更多防止这种类型攻击的信息。

比较session-fixation-protection选项

<http auto-config="true" use-expressions="true"><!-- ... --> <session-management> <concurrency-control max-sessions="1"/> </session-management></http>

<listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class></listener><listener> <listener-class> org.springframework.security.web.session .HttpSessionEventPublisher </listener-class></listener><servlet> <servlet-name>dogstore</servlet-name>

????????? 这两个配置完成,session的并发控制功能也就激活了。让我们看一下它内部是如何工作的,然后我们将会通过几步操作来查看它对用户的session的保护功能。


?SessionAuthenticationStrategy的一个扩展类即o.s.s.web.authentication.session.ConcurrentSessionControlStrategy提供方法来实现新session的跟踪以及session并发控制的实际增强功能。每次用户访问这个安全站点时,SessionManagementFilter将会比照SessionRegistry检查这个活跃的session。如果用户活跃的session不在SessionRegistry这个活跃session列表中,最近最少被使用的session将会立即过期。

将会显示以下的信息:


《Spring Security3》第六章第三一部分翻译(Session的管理和并发)
?尽管不很友好,但是它能够表明session已经被软件强制失效了。如果你是一个攻击者,现在你可能会很灰心。但是,如果你是一个合法的用户,你可能会很迷惑,因为这显然不是一个友好的方式来表明JBCP Pets一直关注着你的安全。

<http auto-config="true" use-expressions="true"><!-- ... --> <session-management> <concurrency-control max-sessions="1" expired-url= "/login.do?error=expired"/> </session-management></http>

?这样在我们的应用中,就会将用户重定向到登录form,并且我们可以修改这个页面来展现用户友好的信息来表明发现了多个活跃的session,从而需要重新登录。当然,这个URL是完全随意的,并根据你应用的需求来进行相应的调整。

Session并发控制的其它好处

SessionRegistry sessionRegistry;@ModelAttribute("numUsers") public int getNumberOfUsers() { return sessionRegistry.getAllPrincipals().size(); }

?我们可以看到这暴露了一个能够在Spring MVC JSP页面中能够使用的属性,所以我们添加一个页脚footer.jsp到JBCP Pets站点中并使用这个属性。

?

<div id="footer">  ${numUsers} user(s) are logged in!</div></body></html>

?如果你重新启动应用并登录,能够在每个页面的底部看到活动用户的数量。


《Spring Security3》第六章第三一部分翻译(Session的管理和并发)
?很简单,但是它阐述了作为Spring Security一部分所提供的session跟踪的好处——尤其是你能够直接使用这个内置的功能。

@RequestMapping("/account/listActiveUsers.do")public void listActiveUsers(Model model) { Map<Object,Date> lastActivityDates = new HashMap<Object, Date>(); for(Object principal: sessionRegistry.getAllPrincipals()) { // a principal may have multiple active sessions for(SessionInformation session : sessionRegistry.getAllSessions(principal, false)) {// no last activity stored if(lastActivityDates.get(principal) == null) { lastActivityDates.put(principal, session.getLastRequest()); } else { // check to see if this session is newer than the last stored Date prevLastRequest = lastActivityDates.get(principal); if(session.getLastRequest().after(prevLastRequest)) { // update if so lastActivityDates.put(principal, session.getLastRequest()); } } } } model.addAttribute("activeUsers", lastActivityDates);}

?这个方法使用了SessionRegistry的两个API。

了解了SessionRegistryAPI方法,listActiveUsers方法的逻辑就很简单了——检索注册表中所有的活跃用户并寻找最近活动的session。Principal以及最近活跃的时间戳信息插入到一个Map中用来在UI中展现。

UI页面通过使用JSTL结构变得很简单了。在WEB-INF/views/account目录下,创建listActiveUsers.jsp,内容如下(简便起见,我们省略了头部和尾部信息):

?

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><h1>Active Users</h1><ul>  <c:forEach items="${activeUsers}" var="uinfo">    <li><strong>${uinfo.key.username}</strong>     / Last Active: <strong>${uinfo.value}</strong></li>  </c:forEach></ul>

?最后,当我们导航到http://localhost:8080/JBCPPets/account/listActiveUsers.do,页面基本如下:


《Spring Security3》第六章第三一部分翻译(Session的管理和并发)
?通过这些例子,你已经了解到了SessionRegistry的威力。我们甚至可以扩展SessionRegistry来跟踪用户活动的附加信息,如最后访问的页面、最后的行为等——这对基于Spring Security构建管理界面来说是很有用的。

1 楼 salever 昨天   一下午从第一张看到这里,周末可以好好地消化了,多谢楼主!

热点排行