Spring Security——session管理

  Spring Security经过http元素下的子元素session-management提供了对Http Session管理的支持。 web

 

1.1     检测session超时

       Spring Security能够在用户使用已经超时的sessionId进行请求时将用户引导到指定的页面。这个能够经过以下配置来实现。 spring

   <security:http> 浏览器

      ... 服务器

      <!-- session管理,invalid-session-url指定使用已经超时的sessionId进行请求须要重定向的页面 --> cookie

      <security:session-management invalid-session-url="/session_timeout.jsp"/> session

      ... jsp

   </security:http> url

 

       须要注意的是session超时的重定向页面应当是不须要认证的,不然再重定向到session超时页面时会直接转到用户登陆页面。此外若是你使用这种方式来检测session超时,当你退出了登陆,而后在没有关闭浏览器的状况下又从新进行了登陆,Spring Security可能会错误的报告session已经超时。这是由于即便你已经退出登陆了,但当你设置session无效时,对应保存session信息的cookie并无被清除,等下次请求时仍是会使用以前的sessionId进行请求。解决办法是显示的定义用户在退出登陆时删除对应的保存session信息的cookie。 spa

   <security:http> orm

      ...

      <!-- 退出登陆时删除session对应的cookie -->

      <security:logout delete-cookies="JSESSIONID"/>

      ...

   </security:http>

       此外,Spring Security并不保证这对全部的Servlet容器都有效,到底在你的容器上有没有效,须要你本身进行实验。

 

1.2     concurrency-control

       一般状况下,在你的应用中你可能只但愿同一用户在同时登陆屡次时只能有一个是成功登入你的系统的,一般对应的行为是后一次登陆将使前一次登陆失效,或者直接限制后一次登陆。Spring Security的session-management为咱们提供了这种限制。

       首先须要咱们在web.xml中定义以下监听器。

   <listener>

   <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>

   </listener>

 

       在session-management元素下有一个concurrency-control元素是用来限制同一用户在应用中同时容许存在的已经经过认证的session数量。这个值默认是1,能够经过concurrency-control元素的max-sessions属性来指定。

   <security:http auto-config="true">

      ...

      <security:session-management>

         <security:concurrency-control max-sessions="1"/>

      </security:session-management>

      ...

   </security:http>

 

       当同一用户同时存在的已经经过认证的session数量超过了max-sessions所指定的值时,Spring Security的默认策略是将先前的设为无效。若是要限制用户再次登陆能够设置concurrency-control的error-if-maximum-exceeded的值为true。

 

   <security:http auto-config="true">

      ...

      <security:session-management>

         <security:concurrency-control max-sessions="1" error-if-maximum-exceeded="true"/>

      </security:session-management>

      ...

   </security:http>

 

       设置error-if-maximum-exceeded为true后若是你以前已经登陆了,而后想再次登陆,那么系统将会拒绝你的登陆,同时将重定向到由form-login指定的authentication-failure-url。若是你的再次登陆是经过Remember-Me来完成的,那么将不会转到authentication-failure-url,而是返回未受权的错误码401给客户端,若是你仍是想重定向一个指定的页面,那么你能够经过session-management的session-authentication-error-url属性来指定,同时须要指定该url为不受Spring Security管理,即经过http元素设置其secure=”none”。

   <security:http security="none" pattern="/none/**" />

   <security:http>

      <security:form-login/>

      <security:logout/>

      <security:intercept-url pattern="/**" access="ROLE_USER"/>

      <!-- session-authentication-error-url必须是不受Spring Security管理的 -->

      <security:session-management session-authentication-error-url="/none/session_authentication_error.jsp">

         <security:concurrency-control max-sessions="1" error-if-maximum-exceeded="true"/>

      </security:session-management>

      <security:remember-me data-source-ref="dataSource"/>

   </security:http>

 

       在上述配置中咱们配置了session-authentication-error-url为“/none/session_authentication_error.jsp”,同时咱们经过<security:http security="none" pattern="/none/**" />指定了以“/none”开始的全部URL都不受Spring Security控制,这样当用户进行登陆之后,再次经过Remember-Me进行自动登陆时就会重定向到“/none/session_authentication_error.jsp”了。

       在上述配置中为何咱们须要经过<security:http security="none" pattern="/none/**" />指定咱们的session-authentication-error-url不受Spring Security控制呢?把它换成<security:intercept-url pattern="/none/**"access="IS_AUTHENTICATED_ANONYMOUSLY"/>不行吗?这就涉及到以前所介绍的它们二者之间的区别了。前者表示不使用任何Spring Security过滤器,天然也就不须要经过Spring Security的认证了,然后者是会被Spring Security的FilterChain进行过滤的,只是其对应的URL能够匿名访问,即不须要登陆就可访问。使用后者时,REMEMBER_ME_FILTER检测到用户没有登陆,同时其又提供了Remember-Me的相关信息,这将使得REMEMBER_ME_FILTER进行自动登陆,那么在自动登陆时因为咱们限制了同一用户同一时间只能登陆一次,后来者将被拒绝登陆,这个时候将重定向到session-authentication-error-url,重定向访问session-authentication-error-url时,通过REMEMBER_ME_FILTER时又会自动登陆,这样就造成了一个死循环。因此session-authentication-error-url应当使用<security:http security="none" pattern="/none/**" />设置为不受Spring Security控制,而不是使用<security:intercept-url pattern="/none/**"access="IS_AUTHENTICATED_ANONYMOUSLY"/>。

 

       此外,能够经过expired-url属性指定当用户尝试使用一个因为其再次登陆致使session超时的session时所要跳转的页面。同时须要注意设置该URL为不须要进行认证。

   <security:http auto-config="true">

      <security:form-login/>

      <security:logout/>

      <security:intercept-url pattern="/expired.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY"/>

      <security:intercept-url pattern="/**" access="ROLE_USER"/>

      <security:session-management>

         <security:concurrency-control max-sessions="1" expired-url="/expired.jsp" />

      </security:session-management>

   </security:http>

 

1.3     session 固定攻击保护

       session固定是指服务器在给客户端建立session后,在该session过时以前,它们都将经过该session进行通讯。session 固定攻击是指恶意攻击者先经过访问应用来建立一个session,而后再让其余用户使用相同的session进行登陆(好比经过发送一个包含该sessionId参数的连接),待其余用户成功登陆后,攻击者利用原来的sessionId访问系统将和原用户得到一样的权限。Spring Security默认是对session固定攻击采起了保护措施的,它会在用户登陆的时候从新为其生成一个新的session。若是你的应用不须要这种保护或者该保护措施与你的某些需求相冲突,你能够经过session-management的session-fixation-protection属性来改变其保护策略。该属性的可选值有以下三个。

l  migrateSession:这是默认值。其表示在用户登陆后将新建一个session,同时将原session中的attribute都copy到新的session中。

l  none:表示继续使用原来的session。

l  newSession:表示从新建立一个新的session,可是不copy原session拥有的attribute。

 

(注:本文是基于Spring Security3.1.6所写)

(注:原创文章,转载请注明出处。原文地址:http://haohaoxuexi.iteye.com/blog/2208429

相关文章
相关标签/搜索