cas和springSecurity集成后各負責功能介紹:
cas:
登錄認證(單點登錄)也就是在當前項目下登錄, 互相信任的其他項目可以自動認證是否登錄過.
springSecurity:
權限管理(判斷當前登錄過的用戶的權限是管理員還是普通用戶都能訪問哪些資源)
用戶請求進入系統先訪問cas, 經過了cas的登錄流程后, cas會將登錄后的用戶的用戶名交給springSecurity框架
springSecurity框架負責判斷當前用戶具有哪些訪問權限.
什么是跨域訪問:
跨域訪問是在頁面ajax操作的時候, 也是當前系統的頁面發送請求到另一個系統的controller,
只要請求的url中, 協議, 域名(IP地址), 端口號其中這三項任意一項發生改變則發生跨域訪問問題.
是由於瀏覽器廠商在開發瀏覽器的時候默認設置了同源策略引起的.
同源策略:
瀏覽器廠商在開發瀏覽器的時候已經在瀏覽器內部內置了同源策略, 要求頁面發送ajax訪問的時候, 請求的url中
協議, 域名(IP地址), 端口號都不允許發生改變, 必須跟當前系統的url一樣. 如果發生改變, 則認為不安全.
可以將請求發送出去, 但是瀏覽器不接收返回的數據.
跨域訪問瀏覽器控制台顯示內容:
已攔截跨源請求:同源策略禁止讀取位於 http://localhost:9107/cart/addGoodsToCartList.do?itemId=1369297&num=1
的遠程資源。(原因:CORS 請求未能成功)
跨域解決方案:
1.使用注解@CrossOrigin(origins="http://localhost:8086",allowCredentials="true")
加在需要跨域訪問的controller方法上, origins="http://localhost:8086"地址為數據返回到哪台服務器的地址.
原理是相當於更改, 請求頭和響應頭.讓瀏覽器放開對這次請求跨域的攔截.
2. jsonp解決:
如果頁面使用jquery發送請求, 可以將發送的數據類型設置為jsonp.
那么jquery在發送請求的同時, 會自動生成一個令牌發送給controller,
后台controller需要接收jquery發送來的令牌, 在返回數據的時候需要將令牌一起返回.
jquery接收返回的響應的時候, 判斷令牌是否為自己發送的, 是則接收數據
如果不是自己發送的令牌, 則拒絕接收響應的數據.
spring-security.xml
<?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.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd"> <http pattern="/css/**" security="none"></http> <http pattern="/img/**" security="none"></http> <http pattern="/js/**" security="none"></http> <http pattern="/plugins/**" security="none"></http> <http pattern="/register.html" security="none"></http> <http pattern="/user/add.do" security="none"></http> <http pattern="/user/sendCode.do" security="none"></http> <!-- entry-point-ref 入口點引用 --> <http use-expressions="false" entry-point-ref="casProcessingFilterEntryPoint"> <!--攔截所有路徑,不包括放行的路徑--> <intercept-url pattern="/**" access="ROLE_USER"/> <csrf disabled="true"/> <!-- custom-filter為過濾器, position 表示將過濾器放在指定的位置上,before表示放在指定位置之前 ,after表示放在指定的位置之后 --> <custom-filter ref="casAuthenticationFilter" position="CAS_FILTER" /> <custom-filter ref="requestSingleLogoutFilter" before="LOGOUT_FILTER"/> <custom-filter ref="singleLogoutFilter" before="CAS_FILTER"/> </http> <!-- CAS入口點 開始 --> <beans:bean id="casProcessingFilterEntryPoint" class="org.springframework.security.cas.web.CasAuthenticationEntryPoint"> <!-- 單點登錄服務器登錄URL --> <beans:property name="loginUrl" value="http://192.168.200.128:9100/cas/login"/> <beans:property name="serviceProperties" ref="serviceProperties"/> </beans:bean> <beans:bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties"> <!--service 配置自身工程的根地址+/login/cas --> <beans:property name="service" value="http://localhost:8083/login/cas"/> </beans:bean> <!-- CAS入口點 結束 --> <!-- 認證過濾器 開始 --> <beans:bean id="casAuthenticationFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter"> <beans:property name="authenticationManager" ref="authenticationManager"/> </beans:bean> <!-- 認證管理器 --> <authentication-manager alias="authenticationManager"> <authentication-provider ref="casAuthenticationProvider"> </authentication-provider> </authentication-manager> <!-- 認證提供者 --> <beans:bean id="casAuthenticationProvider" class="org.springframework.security.cas.authentication.CasAuthenticationProvider"> <beans:property name="authenticationUserDetailsService"> <beans:bean class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper"> <beans:constructor-arg ref="userDetailsService" /> </beans:bean> </beans:property> <beans:property name="serviceProperties" ref="serviceProperties"/> <!-- ticketValidator 為票據驗證器 --> <beans:property name="ticketValidator"> <beans:bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator"> <beans:constructor-arg index="0" value="http://192.168.200.128:9100/cas"/> </beans:bean> </beans:property> <beans:property name="key" value="an_id_for_this_auth_provider_only"/> </beans:bean> <!-- 認證類 --> <beans:bean id="userDetailsService" class="cn.itcast.core.service.UserDetailServiceImpl"/> <!-- 認證過濾器 結束 --> <!-- 單點登出 開始 --> <beans:bean id="singleLogoutFilter" class="org.jasig.cas.client.session.SingleSignOutFilter"/> <!-- 經過此配置,當用戶在地址欄輸入本地工程 /logout/cas --> <beans:bean id="requestSingleLogoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter"> <beans:constructor-arg value="http://192.168.200.128:9100/cas/logout?service=http://localhost:8083"/> <beans:constructor-arg> <beans:bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/> </beans:constructor-arg> <beans:property name="filterProcessesUrl" value="/logout/cas"/> </beans:bean> <!-- 單點登出 結束 --> </beans:beans>
cas權限的判定
package cn.itcast.core.service; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import java.util.ArrayList; /** * 實現springSecurity的UserDetailsService接口, 進入到這里的請求 都是已經經過CAS單點登錄服務器登陸過的 * 在這里獲取這個用戶具有哪些訪問權限集合, 封裝成SpringSecurity需要的User對象, 返回給SpringSecurity. */ public class UserDetailServiceImpl implements UserDetailsService{ @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { //創建權限集合 ArrayList<GrantedAuthority> authList = new ArrayList<GrantedAuthority>(); //向權限集合中加入訪問權限 authList.add(new SimpleGrantedAuthority("ROLE_USER")); //封裝springSecurity需要的User對象返回. return new User(username, "", authList); } }
應用於登錄頁面 商品詳情頁面portal
spring-security.xml
<?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.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd"> <http pattern="/css/**" security="none"></http> <http pattern="/img/**" security="none"></http> <http pattern="/js/**" security="none"></http> <http pattern="/plugins/**" security="none"></http> <http pattern="/index.html" security="none"></http> <http pattern="/search.html" security="none"></http> <http pattern="/cart.html" security="none"></http> <!-- <http pattern="/cart.html" security="none"></http> --> <!-- entry-point-ref 入口點引用 --> <http use-expressions="false" entry-point-ref="casProcessingFilterEntryPoint"> <!-- 匿名角色 IS_AUTHENTICATED_ANONYMOUSLY --> <intercept-url pattern="/cart/*.do" access="IS_AUTHENTICATED_ANONYMOUSLY"></intercept-url> <intercept-url pattern="/itemsearch/*.do" access="IS_AUTHENTICATED_ANONYMOUSLY"></intercept-url> <intercept-url pattern="/**" access="ROLE_USER"/> <csrf disabled="true"/> <!-- custom-filter為過濾器, position 表示將過濾器放在指定的位置上,before表示放在指定位置之前 ,after表示放在指定的位置之后 --> <custom-filter ref="casAuthenticationFilter" position="CAS_FILTER" /> <custom-filter ref="requestSingleLogoutFilter" before="LOGOUT_FILTER"/> <custom-filter ref="singleLogoutFilter" before="CAS_FILTER"/> </http> <!-- CAS入口點 開始 --> <beans:bean id="casProcessingFilterEntryPoint" class="org.springframework.security.cas.web.CasAuthenticationEntryPoint"> <!-- 單點登錄服務器登錄URL --> <beans:property name="loginUrl" value="http://192.168.200.128:9100/cas/login"/> <beans:property name="serviceProperties" ref="serviceProperties"/> </beans:bean> <beans:bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties"> <!--service 配置自身工程的根地址+/login/cas --> <beans:property name="service" value="http://localhost:8080/login/cas"/> </beans:bean> <!-- CAS入口點 結束 --> <!-- 認證過濾器 開始 --> <beans:bean id="casAuthenticationFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter"> <beans:property name="authenticationManager" ref="authenticationManager"/> </beans:bean> <!-- 認證管理器 --> <authentication-manager alias="authenticationManager"> <authentication-provider ref="casAuthenticationProvider"> </authentication-provider> </authentication-manager> <!-- 認證提供者 --> <beans:bean id="casAuthenticationProvider" class="org.springframework.security.cas.authentication.CasAuthenticationProvider"> <beans:property name="authenticationUserDetailsService"> <beans:bean class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper"> <beans:constructor-arg ref="userDetailsService" /> </beans:bean> </beans:property> <beans:property name="serviceProperties" ref="serviceProperties"/> <!-- ticketValidator 為票據驗證器 --> <beans:property name="ticketValidator"> <beans:bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator"> <beans:constructor-arg index="0" value="http://192.168.200.128:9100/cas"/> </beans:bean> </beans:property> <beans:property name="key" value="an_id_for_this_auth_provider_only"/> </beans:bean> <!-- 認證類 --> <beans:bean id="userDetailsService" class="cn.itcast.core.service.UserDetailServiceImpl"/> <!-- 認證過濾器 結束 --> <!-- 單點登出 開始 --> <beans:bean id="singleLogoutFilter" class="org.jasig.cas.client.session.SingleSignOutFilter"/> <!-- 經過此配置,當用戶在地址欄輸入本地工程 /logout/cas --> <beans:bean id="requestSingleLogoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter"> <beans:constructor-arg value="http://192.168.200.128:9100/cas/logout?service=http://localhost:8080"/> <beans:constructor-arg> <beans:bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/> </beans:constructor-arg> <beans:property name="filterProcessesUrl" value="/logout/cas"/> </beans:bean> <!-- 單點登出 結束 --> </beans:beans>