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>