【Spring Security實戰系列】Spring Security實戰(七)
阿新 • • 發佈:2019-01-27
<?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"
xmlns:sec="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<!-- 配置不過濾的資源(靜態資源及登入相關).是忽略攔截某些資源的意思,主要是針對靜態資源 -->
<http pattern="/**/*.css" security="none"></http>
<http pattern="/**/*.jpg" security="none"></http>
<http pattern="/**/*.jpeg" security="none"></http>
<http pattern="/**/*.gif" security="none"></http>
<http pattern="/**/*.png" security="none"></http>
<http pattern="/js/*.js" security="none"></http>
<http pattern="/login.jsp" security="none"></http>
<http pattern="/getCode" security="none" /><!-- 不過濾驗證碼 -->
<http pattern="/test/**" security="none"></http><!-- 不過濾測試內容 -->
<http auto-config="false" entry-point-ref="loginUrlAuthenticationEntryPoint">
<!--<intercept-url pattern="/login.jsp" access="permitAll" />-->
<!-- 表示訪問app.jsp時,需要ROLE_SERVICE許可權 -->
<!--<intercept-url pattern="/adminPage.jsp" access="hasRole('ROLE_ADMIN')"></intercept-url>-->
<!--表示訪問任何資源都需要ROLE_ADMIN許可權。-->
<!-- <intercept-url pattern="/**" access="hasRole('ROLE_USER')"></intercept-url>-->
<!--
登陸頁面肯定是不能攔截的,任何人都應該可以訪問,
<intercept-url pattern="/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" />配置表示允許匿名使用者訪問,
就是不用身份都可以訪問;
還有另一種配置方式:<http pattern="/login.jsp" security="none"></http>,這種配置達到的目的都是一樣的。
-->
<!--
form-login這個標籤是配置登陸頁面的,其中的屬性login-page是配置登陸頁面的,
default-target-url配置登陸成功後跳轉到的頁面,
authentication-failure-url配置認證失敗後的跳轉頁面。
form-login標籤中還有一個特別要注意的屬性use-expressions,如果設定為true,
這配置access就要做相應的改變,否則專案啟動的時候會報錯。
如果use-expressns="true"時,則表示改為 SpEL 表示式。 SpEL 允許使用特定的訪問控制規則表示式語言。
與簡單的字串如 ROLE_USER 不同,配置檔案可以指明表示式語言觸發方法呼叫、引用系統屬性、計算機值等等。
如 :<intercept-url pattern="/login.jsp" access="permitAll" />
-->
<!--<form-login login-page="/login.jsp" default-target-url="/index.jsp"
authentication-failure-url="/login.jsp?error=true"></form-login>-->
<!--
logout這個標籤用來配置退出或者登出,其中的屬性invalidate-session,
配置否是要清除session,logout-success-url配置登出成功後的跳轉頁面,
logout-url提交退出或者登出的地址,因此我們在配置退出或者登出的時候,
只需要將url設定為/j_spring_security_logout即可,這個地址也是security內部實現了的。
-->
<logout invalidate-session="true" logout-success-url="/login.jsp"
logout-url="/j_spring_security_logout"></logout>
<custom-filter ref="myUsernamePasswordAuthenticationFilter" position="FORM_LOGIN_FILTER"></custom-filter>
<!--========================新增內容==========start=============================================-->
<!--替換預設REMEMBER_ME_FILTER-->
<custom-filter ref="rememberMeFilter" position="REMEMBER_ME_FILTER"/>
<!--========================新增內容=======================================================-->
<!--
通過配置custom-filter來增加過濾器,
before="FILTER_SECURITY_INTERCEPTOR"表示在Springsecurity預設的過濾器之前執行
-->
<custom-filter ref="filterSecurityInterceptor" before="FILTER_SECURITY_INTERCEPTOR"></custom-filter>
<!-- max-sessions只容許一個賬號登入,error-if-maximum-exceeded 後面賬號登入後踢出前一個賬號,
expired-url session過期跳轉介面
如果concurrency-control標籤配置了error-if-maximum-exceeded="true",max-sessions="1",
那麼第二次登入時,是登入不了的。如果error-if-maximum-exceeded="false",
那麼第二次是能夠登入到系統的,但是第一個登入的賬號再次發起請求時,會跳轉到expired-url配置的url中-->
<session-management session-authentication-error-url="/login.jsp">
<concurrency-control max-sessions="1" error-if-maximum-exceeded="false"
expired-url="/login.jsp" session-registry-ref="sessionRegistry" />
</session-management>
<expression-handler ref="webexpressionHandler" ></expression-handler>
</http>
<beans:bean id="loginUrlAuthenticationEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:property name="loginFormUrl" value="/login.jsp"></beans:property>
</beans:bean>
<!-- 匯入資料來源 -->
<beans:import resource="applicationContext-dataSource.xml"></beans:import>
<beans:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl"/>
<!--配置web端使用許可權控制-->
<beans:bean id="webexpressionHandler" class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"/>
<beans:bean id="bulider" class="cn.quan.ssm.sec.JdbcRequestMapBulider">
<beans:property name="dataSource" ref="mysqlDataSource"></beans:property>
<beans:property name="resourceQuery" value="select re.res_string,r.`name` from role r,resc re,resc_role rr where r.id=rr.role_id and re.id=rr.resc_id" />
</beans:bean>
<!--配置自定義的過濾器:配置MyUsernamePasswordAuthenticationFilter並將其加入到FilterChain中去-->
<beans:bean id="myUsernamePasswordAuthenticationFilter"
class="cn.quan.ssm.sec.dao.MyUsernamePasswordAuthenticationFilter">
<!--filterProcessesUrl屬性為登陸的過濾的地址-->
<beans:property name="filterProcessesUrl" value="/j_spring_security_check" />
<!--authenticationManager為authentication-manager標籤中配置的-->
<beans:property name="authenticationManager" ref="authenticationManager" />
<!--authenticationSuccessHandler為驗證成功後跳轉的處理器-->
<beans:property name="authenticationSuccessHandler" ref="loginLogAuthenticationSuccessHandler" />
<!--authenticationFailureHandler為驗證失敗的處理器-->
<beans:property name="authenticationFailureHandler" ref="simpleUrlAuthenticationFailureHandler" />
<!--========================新增內容==========start=============================================-->
<beans:property name="rememberMeServices" ref="rememberMeServices" />
<!--========================新增內容==========end=============================================-->
</beans:bean>
<beans:bean id="loginLogAuthenticationSuccessHandler"
class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<beans:property name="targetUrlParameter" value="/index.jsp"></beans:property>
</beans:bean>
<beans:bean id="simpleUrlAuthenticationFailureHandler"
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<beans:property name="defaultFailureUrl" value="/login.jsp"></beans:property>
</beans:bean>
<beans:bean id="filterSecurityInterceptor"
class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<!-- 使用者擁有的許可權 -->
<beans:property name="accessDecisionManager" ref="accessDecisionManager" />
<!-- 使用者是否擁有所請求資源的許可權 -->
<beans:property name="authenticationManager" ref="authenticationManager" />
<!-- 資源與許可權對應關係 -->
<beans:property name="securityMetadataSource" ref="securityMetadataSource" />
</beans:bean>
<!--授權管理器:acl領域模型-->
<beans:bean id="accessDecisionManager" class="cn.quan.ssm.sec.dao.MyAccessDecisionManager" />
<!--認證管理-->
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="userDetailsService">
</authentication-provider>
<!--========================新增內容==========start=============================================-->
<!-- 記住密碼 -->
<authentication-provider ref="rememberMeAuthenticationProvider"></authentication-provider>
<!--========================新增內容==========end=============================================-->
</authentication-manager>
<!--========================新增內容==========start=============================================-->
<!--
說明:dataSource就是連線資料庫的資料來源;usersByUsernameQuery就是配置jdbc-user-service時候的users-by-username-query,
這個是根據使用者名稱來查詢使用者的sql語句;同理authoritiesByUsernameQuery就是對應的authorities-by-username-query,
這個用來根據使用者名稱查詢對應的許可權。
-->
<!-- 配置userDetailsService -->
<beans:bean id="userDetailsService"
class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
<beans:property name="usersByUsernameQuery"
value="select username,password,status as enabled from user where username = ?" />
<beans:property name="authoritiesByUsernameQuery"
value="select user.username,role.name from user,role,user_role
where user.id=user_role.user_id and
user_role.role_id=role.id and user.username=?" />
<beans:property name="dataSource" ref="mysqlDataSource" />
</beans:bean>
<!--配置rememberMe的過濾器: Remember-Me 對應的 Filter-->
<beans:bean id="rememberMeFilter"
class="org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
<beans:property name="rememberMeServices" ref="rememberMeServices" />
<beans:property name="authenticationManager" ref="authenticationManager" />
</beans:bean>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~基於簡單加密的方式~~start~~~~~~不存資料庫~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<!-- rememberService -->
<!-- RememberMeServices 的實現 -->
<beans:bean id="rememberMeServices"
class="org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
<beans:property name="userDetailsService" ref="userDetailsService" />
<beans:property name="key" value="zmc" />
<!-- 指定 request 中包含的使用者是否選擇了記住我的引數名 -->
<beans:property name="parameter" value="rememberMe"/>
</beans:bean>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~基於簡單加密的方式~~end~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<!-- 記住密碼 -->
<!-- key 值需與對應的 RememberMeServices 保持一致 -->
<beans:bean id="rememberMeAuthenticationProvider"
class="org.springframework.security.authentication.RememberMeAuthenticationProvider" >
<beans:property name="key" value="zmc" />
</beans:bean>
<!--========================新增內容==========end=============================================-->
<!--自定義的切入點-->
<beans:bean id="securityMetadataSource"
class="cn.quan.ssm.sec.dao.MyFilterInvocationSecurityMetadataSource">
<beans:property name="bulider" ref="bulider"></beans:property>
</beans:bean>
</beans:beans>