配置檔案詳解
目錄
配置檔案詳解
3.X
4.X
單點登入配置session-management
1.1 檢測session逾時
1.2 concurrency-control
1.3 session 固定攻擊保護
3.X
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<global-method-security pre-post-annotations="enabled">
</global-method-security>
<!-- 該路徑下的資源不用過濾 -->
<http pattern="/include/js/**" security="none" />
<http pattern="/include/css/**" security="none" />
<http pattern="/include/scripts/**" security="none" />
<http pattern="/include/jsp/**" security="none" />
<http pattern="/images/**" security="none" />
<http pattern="/login.jsp" security="none" />
<!--auto-config = true 則使用from-login. 如果不使用該屬性 則預設為http-basic(沒有session).-->
<!-- lowercase-comparisons:表示URL比較前先轉為小寫。-->
<!-- path-type:表示使用Apache Ant的比對模式。-->
<!--access-denied-page:通路拒絕時轉向的頁面。-->
<!-- access-decision-manager-ref:指定了自定義的通路政策管理器。-->
<http use-expressions="true" auto-config="true"
access-denied-page="/include/jsp/timeout.jsp">
<!--login-page:指定登入頁面。 -->
<!-- login-processing-url:指定了客戶在登入頁面中按下 Sign In 按鈕時要通路的 URL。-->
<!-- authentication-failure-url:指定了身份驗證失敗時跳轉到的頁面。-->
<!-- default-target-url:指定了成功進行身份驗證和授權後預設呈現給使用者的頁面。-->
<!-- always-use-default-target:指定了是否在身份驗證通過後總是跳轉到default-target-url屬性指定的URL。
-->
<form-login login-page="/login.jsp" default-target-url='/system/default.jsp'
always-use-default-target="true" authentication-failure-url="/login.jsp?login_error=1" />
<!--logout-url:指定了用于響應退出系統請求的URL。其預設值為:/j_spring_security_logout。-->
<!-- logout-success-url:退出系統後轉向的URL。-->
<!-- invalidate-session:指定在退出系統時是否要銷毀Session。-->
<logout invalidate-session="true" logout-success-url="/login.jsp"
logout-url="/j_spring_security_logout" />
<!-- 實作免登陸驗證 -->
<remember-me />
<!-- max-sessions:允許使用者帳号登入的次數。範例限制使用者隻能登入一次。-->
<!-- 此值表示:使用者第二次登入時,前一次的登入資訊都被清空。-->
<!-- exception-if-maximum-exceeded:預設為false,-->
<!-- 當exception-if-maximum-exceeded="true"時系統會拒絕第二次登入。-->
<session-management invalid-session-url="/login.jsp"
session-fixation-protection="none">
<concurrency-control max-sessions="1"
error-if-maximum-exceeded="false" />
</session-management>
<custom-filter ref="myFilter" before="FILTER_SECURITY_INTERCEPTOR" />
<session-management
session-authentication-strategy-ref="sas" />
</http>
<beans:bean id="sas"
class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
<beans:constructor-arg name="sessionRegistry"
ref="sessionRegistry" />
<beans:property name="maximumSessions" value="1" />
<!-- 防止session攻擊 -->
<beans:property name="alwaysCreateSession" value="true" />
<beans:property name="migrateSessionAttributes" value="false" />
<!-- 同一個帳号 同時隻能一個人登入 -->
<beans:property name="exceptionIfMaximumExceeded"
value="false" />
</beans:bean>
<beans:bean id="sessionRegistry"
class="org.springframework.security.core.session.SessionRegistryImpl" />
<!--
事件監聽:實作了ApplicationListener監聽接口,包括AuthenticationCredentialsNotFoundEvent 事件,-->
<!-- AuthorizationFailureEvent事件,AuthorizedEvent事件, PublicInvocationEvent事件-->
<beans:bean
class="org.springframework.security.authentication.event.LoggerListener" />
<!-- 自定義資源檔案 提示資訊 -->
<beans:bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<beans:property name="basenames" value="classpath:message_zh_CN">
</beans:property>
</beans:bean>
<!-- 配置過濾器 -->
<beans:bean id="myFilter"
class="com.taskmanager.web.security.MySecurityFilter">
<!-- 使用者擁有的權限 -->
<beans:property name="authenticationManager" ref="myAuthenticationManager" />
<!-- 使用者是否擁有所請求資源的權限 -->
<beans:property name="accessDecisionManager" ref="myAccessDecisionManager" />
<!-- 資源與權限對應關系 -->
<beans:property name="securityMetadataSource" ref="mySecurityMetadataSource" />
</beans:bean>
<!-- 實作了UserDetailsService的Bean -->
<authentication-manager alias="myAuthenticationManager">
<authentication-provider user-service-ref="myUserDetailServiceImpl">
<!-- 登入 密碼 采用MD5加密 -->
<password-encoder hash="md5" ref="passwordEncoder">
</password-encoder>
</authentication-provider>
</authentication-manager>
<!-- 驗證使用者請求資源 是否擁有權限 -->
<beans:bean id="myAccessDecisionManager"
class="com.taskmanager.web.security.MyAccessDecisionManager">
</beans:bean>
<!-- 系統運作時加載 系統要攔截的資源 與使用者請求時要過濾的資源 -->
<beans:bean id="mySecurityMetadataSource"
class="com.taskmanager.web.security.MySecurityMetadataSource">
<beans:constructor-arg name="powerService" ref="powerService">
</beans:constructor-arg>
</beans:bean>
<!-- 擷取使用者登入角色資訊 -->
<beans:bean id="myUserDetailServiceImpl"
class="com.taskmanager.web.security.MyUserDetailServiceImpl">
<beans:property name="userService" ref="userService"></beans:property>
</beans:bean>
<!-- 使用者的密碼加密或解密 -->
<beans:bean id="passwordEncoder"
class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" />
</beans:beans>
4.X
<beans:beans
xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<context:component-scan base-package="com.framework.security"/>
<!--<http pattern="/pm/**" security="none" />-->
<http pattern="/login.jsp" security="none" />
<http pattern="/common/**" security="none" />
<http pattern="/*.ico" security="none" />
<http use-expressions="false" >
<!-- IS_AUTHENTICATED_ANONYMOUSLY 匿名登入 -->
<intercept-url pattern="/login" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/pm/**/*.jsp" access="ROLE_STATIC" />
<form-login login-page="/login" authentication-failure-url="/login?error=1" authentication-success-forward-url="/main.to" />
<logout invalidate-session="true" logout-url="/logout" logout-success-url="/" />
<http-basic/>
<headers >
<frame-options disabled="true"></frame-options>
</headers>
<csrf token-repository-ref="csrfTokenRepository" />
<session-management session-authentication-error-url="/frame.expired" >
<!-- max-sessions隻容許一個賬号登入,error-if-maximum-exceeded 後面賬号登入後踢出前一個賬号,expired-url session過期跳轉界面 -->
<concurrency-control max-sessions="1" error-if-maximum-exceeded="false" expired-url="/frame.expired" session-registry-ref="sessionRegistry" />
</session-management>
<expression-handler ref="webexpressionHandler" ></expression-handler>
</http>
<beans:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" />
<beans:bean id="userDetailsService" class="com.framework.security.UserDetailsServiceImpl" />
<!--配置web端使用權限控制-->
<beans:bean id="webexpressionHandler" class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler" />
<authentication-manager >
<authentication-provider ref="authenticationProvider" />
</authentication-manager>
<!-- 自定義userDetailsService, 鹽值加密 -->
<beans:bean id="authenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<beans:property name="hideUserNotFoundExceptions" value="true" />
<beans:property name="userDetailsService" ref="userDetailsService" />
<beans:property name="passwordEncoder" ref="passwordEncoder" />
<beans:property name="saltSource" ref="saltSource" />
</beans:bean>
<!-- Md5加密 -->
<beans:bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" />
<!-- 鹽值加密 salt對應資料庫字段-->
<beans:bean id="saltSource" class="org.springframework.security.authentication.dao.ReflectionSaltSource">
<beans:property name="userPropertyToUse" value="salt"/>
</beans:bean>
<beans:bean id="csrfTokenRepository" class="org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository" />
</beans:beans>
轉:https://www.cnblogs.com/yyxxn/p/8080141.html
單點登入配置session-management
Spring Security通過http元素下的子元素session-management提供了對Http Session管理的支援。
1.1 檢測session逾時
Spring Security可以在使用者使用已經逾時的sessionId進行請求時将使用者引導到指定的頁面。這個可以通過如下配置來實作。
<security:http>
...
<!-- session管理,invalid-session-url指定使用已經逾時的sessionId進行請求需要重定向的頁面 -->
<security:session-management invalid-session-url="/session_timeout.jsp"/>
...
</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容器都有效,到底在你的容器上有沒有效,需要你自己進行實驗。
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。
轉:https://www.cnblogs.com/fenglan/p/5913352.html
(注:本文是基于Spring Security3.1.6所寫)