`
lengyun3566
  • 浏览: 452519 次
  • 性别: Icon_minigender_1
  • 来自: 大连
博客专栏
D59180b9-02f1-3380-840c-ea34da46143c
《Spring Secur...
浏览量:383409
社区版块
存档分类
最新评论

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

阅读更多

Session的管理和并发

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

配置session fixation防护

         如果我们使用的是security命名空间的配置方式,session固化防护已经被默认进行了配置。如果我们要指明将其配置为与默认设置一致的话,我们需要这样:

 

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

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

理解session fixation攻击

         Session固化是恶意用户试图窃取系统中一个未认证用户的session。对攻击者来说,可以通过各种技术来获取用户session的唯一标识(例如,JSESSIONID)。如果攻击者创建了带有用户JSESSIONIDcookie或者URL参数,他就能够访问用户的session

         尽管这是一个明显的问题,但是一般情况下,如果用户没有经过认证,他们就还没有输入任何敏感信息(假设站点的安全已经正确规划了)。如果用户认证后依旧使用相同的session标识符,这个问题就会比较更加重要了。如果用户在认证后还使用相同的标识符,那攻击者现在就能访问认证过用户的session,而甚至不必要知道他们的用户名和密码。

         【此时,你可能很不屑并认为在现实世界中这不会发生。实际上,session窃取攻击经常发生。关于这个话题,我们建议(正如在第三章那样)你花些时间阅读由OWASP组织(http://www.owasp.org/)发布的包含重要信息的文章以及学习案例。攻击者和恶意用户是真实存在的,如果你不了解他们常用的技术及如何避免,他们会对你的用户、应用或公司造成真正的损害。】

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



 既然了解了攻击如何进行,接下来我们查看Spring Security如何防止。

使用Spring Security防止session fixation攻击

如果我们能够阻止用户在认证前和认证后使用相同的session,我们就能够让攻击者掌握的session ID信息变得没有用处。Spring Securitysession固化防护解决这个问题的方式就是在用户认证之后明确创建一个新的session并将旧的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中初始化session,并从那里窃取,我们的攻击者将会使用窃取到的sessionFirefox中登录。我们将会使用Internet Explorer Developer Tools IE 8中自带)以及Firefox Web Developer Add-On(第三章中已经给过URL)来查看和控制cookie

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


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

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

 



 为了完成我们的攻击,我们点击“Edit Cookie”选项,并将从IE中复制到粘贴板上的JSESSIONID值粘贴进来,如下图所示:



 我们的session固化攻击完成了!如果此时在Firefox中重新加载页面,你将以IE中已登录用户相同的身份进入系统,并不需要你知道用户名和密码。你是否害怕恶意用户了?

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

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

比较session-fixation-protection选项

         session-fixation-protection属性支持三种不同的选项允许你进行修改:

属性值

描述

none

使得session固化攻击失效,不会配置SessionManagementFilter(除非其它的<session-management>属性不是默认值)

migrateSession

当用户经过认证后分配一个新的session,它保证原session的所有属性移到新session中。我们将在后面的章节中讲解,通过基于bean的方式如何进行这样的配置。

newSession

当用户认证后,建立一个新的session,原(未认证时)session的属性不会进行移到新session中来。

         在大多数场景下,默认行为即migrateSession适用于在用户登录后希望保持重要信息(如点击爱好、购物车等)的站点的站点

通过session的并发控制增强对用户的保护

         紧随session固化防护一个很自然的用户安全增强功能就是session并发控制。如前面所描述的那样,session并发控制能够确保一个用户不能同时拥有超过一个固定数量的活跃session(典型情况是一个)。要确保这个最大值的限制需要涉及到好几个组件的协作以精确跟踪用户session活动的变化。

         让我们配置这个功能并了解其如何工作,然后对其进行测试。

配置session并发控制

         既然我们要了解session并发控制所要涉及的组件,那将其运行环境搭建起来可能会更有感官的了解。首先,我们需要使得ConcurrentSessionFilter生效并在dogstore-security.xml配置。

 

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

 现在,我们需要在web.xml描述文件中配置中使得o.s.s.web.session.HttpSessionEventPublisher生效,这样servelt容器将会通知Spring Security session生命周期的事件(通过HttpSessionEventPublisher)。

 

<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的保护功能。

 

 

理解session并发控制

         我们在前面提到session并发控制试图限制相同的用户以不同的session进行访问。基于我们对session窃取方式攻击的了解,我们可以发现session并发控制能够降低攻击者窃取已登录合法用户session的风险。你觉得为什么会这样呢?

         Session并发控制使用o.s.s.core.session.SessionRegistry来维护一个活跃HTTP session的列表而认证过的用户与其进行关联。当session创建或过期时,注册表中会实时进行更新,基于HttpSessionEventPublisher发布的session生命周期事件来跟踪每一个认证用户的活动session的数量。



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

         在修改后的session并发控制过滤器链中的第二个参与者是o.s.s.web.session.ConcurrentSessionFilter。这个过滤器能够辨认出过期的session(典型情况下,session会被servlet容器或者被ConcurrentSessionControlStrategy强制失效掉)并通知用户他的session已经失效了。

         既然我们已经了解了session并发控制是如何工作的,那对我们来说很容易制造一个它使用的场景。

测试session并发控制

         如同验证session固化攻击那样,我们需要访问两个web浏览器。按一下的步骤:

1.       IE中,以guest用户登录;

2.      接下来,在Firefox中,以相同的用户(guest)登录;

3.       最后,返回到IE中,做任何的动作都可以。你会发现有一个信息提示你的session已经过期了。

将会显示以下的信息:



 尽管不很友好,但是它能够表明session已经被软件强制失效了。如果你是一个攻击者,现在你可能会很灰心。但是,如果你是一个合法的用户,你可能会很迷惑,因为这显然不是一个友好的方式来表明JBCP Pets一直关注着你的安全。

session并发控制对Spring Security的新用户来说是很难掌握的概念。很多用户在还没有完全理解其怎样运行和能带来什么好处时就尝试实现它。如果你想使用这个强大的功能,并且它不像你预想的那样工作,请确保你的配置全部正确并回顾一下本节讲的原理——希望它能帮助你理解什么出错了。】

         在这样的事件发生时,我们应该将用户重定向到登录页,并提供一个信息来说明发生了什么错误。

配置session失效时的重定向地址

         幸运的是,有一种很容易的方法使用户在session并发控制后重定向到友好的页面(一般来说,是登录页),即设置expired-url属性为一个你应用中合法的页面。

 

<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并发控制的其它好处

         Session并发控制的另一个好处是存在SessionRegistry跟踪活跃的session(过期session是可选的)。这意味着我们能够得到系统中运行时的用户活动信息(至少是认证过的用户)。

         即使你不想使用session并发控制,你可以可以这样做。只需将max-sessions的值设置为-1,这样session跟踪会保持可用,但没有最大session个数的限制。

         让我们看两个使用此功能的两种简单方式。

显示活动的用户

         你可能会在线论坛上见到显示系统中当前活跃用户的数量。借助于使用session注册跟踪(通过session并发控制),很容易实现在应用中的每个页面对此进行展现。

         让我们在BaseController中添加一个简单的方法以及bean自动织入。@Autowired

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

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

 

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

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



 很简单,但是它阐述了作为Spring Security一部分所提供的session跟踪的好处——尤其是你能够直接使用这个内置的功能。

         我们能够借助于SessionRegistry进行更高级的收据收集,这对于管理员来说很有用——现在让我们看一下。

显示所有用户的信息

         SessionRegistry跟踪所有活跃用户session的信息。如果你想增强站点的管理,我们可以可以很容易地在一个页面中列出所有的用户活跃用户以及他们在站点中使用的名字。

         让我们为AccountController添加一个新的方法(尽管这样的功能一般会添加在在管理区域,但是此时我们可以假设JBCP Pets并不是一个真正的站点),这个方法将会查找SessionRegistry中的信息并收集当前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

l  getAllPrincipals:返回拥有活跃sessionPrincipal对象(典型情况下为UserDetails对象)所组成的List

l  getAllSessions(principal, includeExpired):得到指定PrincipalSessionInformation组成的List,包含了每个session的信息。也能够包含过期的session

了解了SessionRegistry API方法,listActiveUsers方法的逻辑就很简单了——检索注册表中所有的活跃用户并寻找最近活动的sessionPrincipal以及最近活跃的时间戳信息插入到一个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,页面基本如下:



 通过这些例子,你已经了解到了SessionRegistry的威力。我们甚至可以扩展SessionRegistry来跟踪用户活动的附加信息,如最后访问的页面、最后的行为等——这对基于Spring Security构建管理界面来说是很有用的。

  • 大小: 33.8 KB
  • 大小: 56.4 KB
  • 大小: 32.8 KB
  • 大小: 58.1 KB
  • 大小: 35.8 KB
  • 大小: 46.1 KB
  • 大小: 29.5 KB
  • 大小: 8.4 KB
  • 大小: 28.5 KB
12
0
分享到:
评论
5 楼 dengbin50 2016-07-01  
翻译得不错,学习了!
4 楼 ITCEO1 2016-03-30  
看过lz写的其他模块,确实不错,很负责。
3 楼 u011044460 2015-12-10  
翻译的不错 很精彩
2 楼 stillotherguy 2014-07-24  
nice
1 楼 salever 2012-09-21  
一下午从第一张看到这里,周末可以好好地消化了,多谢楼主!

相关推荐

    Springboot+SpringSecurity+SpringSession+Redis+Mybatis-Plus+Swwager.zip

    本项目“Springboot+SpringSecurity+SpringSession+Redis+Mybatis-Plus+Swwager”整合了Spring Boot、Spring Security、Spring Session、Redis、Mybatis-Plus以及Swagger等技术,旨在构建一个强大的、安全的、具有...

    spring security3 中文版本

    自此之后,Spring Security 成为了 Spring 生态系统中的一个重要组成部分,不断迭代更新,以适应不断变化的安全需求和技术发展。 ##### 1.3 发行版本号 Spring Security 3.0.1 是在 Spring Security 3.0 的基础上...

    spring security 3.x session-management 会话管理失效

    本篇文章将详细解析Spring Security 3.x中的会话管理和相关知识点。 1. **会话管理基础** - 会话在Web应用中扮演着关键角色,它允许服务器存储和跟踪用户的状态。在Spring Security中,会话管理主要涉及到会话固定...

    Spring Security 3 中文 chm

    6. **会话管理(Session Management)**:Spring Security 提供了会话管理功能,包括会话固定保护、会话超时和并发会话控制,防止会话劫持和会话固定攻击。 7. **CSRF(跨站请求伪造)防护**:Spring Security 自动...

    spring security 完整项目实例

    总之,这个"spring security 完整项目实例"涵盖了Spring Security的核心组件和用法,包括用户管理、身份验证、权限控制、会话管理等多个方面。通过学习和实践这个项目,开发者能够深入理解Spring Security的工作原理...

    Spring Security 安全权限管理手册 PDF

    《Spring Security 安全权限管理手册》是一本深入解析Spring Security框架的专业指南,对于正在学习或已经在使用Spring框架的开发者来说,它提供了丰富的知识和实践经验。Spring Security是Spring生态系统中的一个...

    spring security3笔记

    《Spring Security 3笔记》 在深入探讨Spring Security 3的知识点之前,我们先了解下这个框架的基本概念。Spring Security是Spring生态系统中的一个组件,它为Java应用提供了全面的安全服务,包括认证、授权以及Web...

    Spring Security3 张卫滨(译)

    7. **会话管理**:Spring Security提供了会话管理功能,包括会话固定攻击防护(Session Fixation Protection)、会话超时(Session Timeout)和并发会话控制(Concurrent Session Control)。 8. **记住我功能**:...

    springsecurity3.1.pdf

    标题:springsecurity3.1.pdf 描述:springsecurity3.1.pdf 标签:spring security3.1 部分内容:SpringSecurity Reference Documentation by Ben Alex and Luke Taylor 3.1.4.RELEASE **一、Spring Security 3.1...

    SpringSecurity安全框架基础Demo

    这个"SpringSecurity安全框架基础Demo"旨在帮助开发者快速理解和实践Spring Security的核心功能。 **1. 用户认证** 在Spring Security中,用户认证主要由Authentication对象负责。当用户尝试访问受保护的资源时,...

    初识 Spring Security - v1.1.pdf

    - **概念**:Spring Security 提供了丰富的session管理机制,包括检测session超时、并发控制以及防止session固定攻击等功能。 - **检测session超时**:当session超时时,可以通过配置自动清除用户认证信息。 - **...

    SpringSecurity素材.zip

    5. **会话管理(Session Management)**:SpringSecurity可以控制会话的创建、生命周期和并发控制,防止会话固定攻击(Session Fixation)和会话劫持(Session Hijacking)。 6. **CSRF防护(Cross-Site Request ...

    spring security.rar

    4. **会话管理**:Spring Security提供了会话管理功能,可以防止会话固定攻击(Session Fixation),并能控制单个用户的最大并发会话数量。 5. **CSRF保护**:Spring Security默认开启CSRF防护,通过生成并验证CSRF...

    springsecurity3.0.5应用

    5. **Session Management**:Spring Security提供了会话管理策略,如限制同一用户并发会话的数量,防止会话固定攻击。 6. **CSRF防护**:为防止跨站请求伪造(Cross-Site Request Forgery)攻击,Spring Security...

    spring security 3权限管理代码

    6. **会话管理(Session Management)**:Spring Security可以防止会话固定攻击、会话超时以及并发会话控制。它提供了一组配置选项来定制会话创建、销毁和复制的行为。 7. **Remember Me服务**:此功能允许用户在...

    Spring security 4.0

    4. **会话管理**:Spring Security提供会话管理功能,包括会话固定攻击防护(Session Fixation Protection)和并发会话控制(Concurrent Session Control)。例如,当检测到一个用户尝试在另一个地方登录时,可以...

    spring-security源代码

    Spring Security可与OAuth2集成,实现第三方登录和服务提供者的身份验证。 9. **自定义扩展**: 开发者可以自定义认证和授权逻辑,例如自定义认证提供者、权限评估器等。 10. **模块化设计**: Spring Security...

    Spring Security 权限控制中文API

    6. **会话管理(Session Management)**:Spring Security 还提供了会话管理功能,可以防止会话固定攻击(Session Fixation),并支持会话超时和并发会话控制。 7. **CSRF(跨站请求伪造)防护**:默认情况下,...

    Spring security-包含官方文档

    7. **Session Management**:Spring Security 可以控制会话的最大并发数量,防止会话固定攻击,并提供会话超时和会话劫持的防护。 8. **国际化**:Spring Security 支持多语言,可以在认证失败和权限不足时显示不同...

Global site tag (gtag.js) - Google Analytics