1.1 檢測session超時web
1.2 concurrency-controlspring
1.3 session 固定攻擊保護瀏覽器
Spring Security經過http元素下的子元素session-management提供了對Http Session管理的支持。服務器
Spring Security能夠在用戶使用已經超時的sessionId進行請求時將用戶引導到指定的頁面。這個能夠經過以下配置來實現。cookie
<security:http>session
...jsp
<!-- session管理,invalid-session-url指定使用已經超時的sessionId進行請求須要重定向的頁面 -->url
<security:session-management invalid-session-url="/session_timeout.jsp"/>orm
...xml
</security:http>
須要注意的是session超時的重定向頁面應當是不須要認證的,不然再重定向到session超時頁面時會直接轉到用戶登陸頁面。此外若是你使用這種方式來檢測session超時,當你退出了登陸,而後在沒有關閉瀏覽器的狀況下又從新進行了登陸,Spring Security可能會錯誤的報告session已經超時。這是由於即便你已經退出登陸了,但當你設置session無效時,對應保存session信息的cookie並無被清除,等下次請求時仍是會使用以前的sessionId進行請求。解決辦法是顯示的定義用戶在退出登陸時刪除對應的保存session信息的cookie。
<security:http>
...
<!-- 退出登陸時刪除session對應的cookie -->
<security:logout delete-cookies="JSESSIONID"/>
...
</security:http>
此外,Spring Security並不保證這對全部的Servlet容器都有效,到底在你的容器上有沒有效,須要你本身進行實驗。
一般狀況下,在你的應用中你可能只但願同一用戶在同時登陸屢次時只能有一個是成功登入你的系統的,一般對應的行爲是後一次登陸將使前一次登陸失效,或者直接限制後一次登陸。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>
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所寫)