CAS 单点登录/登出 与 SpringSecurity 的整合

匿名 (未验证) 提交于 2019-12-02 22:56:40

CAS 单点登录登出 https://mp.csdn.net/postedit/81201333

SpringSecurity框架 ― ― 安全校验 https://blog.csdn.net/Thor_Selen_Liu/article/details/81220568

前言:

    通过前面两个知识点的学习,下面我们介绍,将两个知识点进行整合使用的方法。在前的 SpringSecurity框架中,我们即做校验又做登录,现在我们 整合 CAS 单点登录,将登录功能交给 CAS 去做,SpringSecurity 只管授权。

话不多说,下面我们以 demo 的方式进行演示:

大概步骤: ① 导入 spring+springsecurity 的依赖 ② 添加配置 springSecurity.xml 和 web.xml ③ 页面 ④ 认证类

 

一、先创建一个 spring-security.xml 工程

 

1. 建立 maven (war) 工程  casclient_demo3,引入 spring 依赖,和spring security 相关依赖,tomcat 端口设为 9003

<dependencies> 	<!-- spring 依赖 --> 	<dependency> 		<groupId>org.springframework</groupId> 		<artifactId>spring-core</artifactId> 		<version>${spring.version}</version> 	</dependency> 	<dependency> 		<groupId>org.springframework</groupId> 		<artifactId>spring-web</artifactId> 		<version>${spring.version}</version> 	</dependency> 	<dependency> 		<groupId>org.springframework</groupId> 		<artifactId>spring-webmvc</artifactId> 		<version>${spring.version}</version> 	</dependency> 	<dependency> 		<groupId>org.springframework</groupId> 		<artifactId>spring-context-support</artifactId> 		<version>${spring.version}</version> 	</dependency> 	<dependency> 		<groupId>org.springframework</groupId> 		<artifactId>spring-test</artifactId> 		<version>${spring.version}</version> 	</dependency> 	<dependency> 		<groupId>org.springframework</groupId> 		<artifactId>spring-jdbc</artifactId> 		<version>${spring.version}</version> 	</dependency> 	<!-- spring security web --> 	<dependency> 		<groupId>org.springframework.security</groupId> 		<artifactId>spring-security-web</artifactId> 		<version>4.1.0.RELEASE</version> 	</dependency> 	<dependency> 		<groupId>org.springframework.security</groupId> 		<artifactId>spring-security-config</artifactId> 		<version>4.1.0.RELEASE</version> 	</dependency> 	<dependency> 		<groupId>javax.servlet</groupId> 		<artifactId>servlet-api</artifactId> 		<version>2.5</version> 		<scope>provided</scope> 	</dependency> 	 </dependencies> <build> 	<plugins> 		<!-- java编译插件 --> 		<plugin> 			<groupId>org.apache.maven.plugins</groupId> 			<artifactId>maven-compiler-plugin</artifactId> 			<version>3.2</version> 			<configuration> 				<source>1.8</source> 				<target>1.8</target> 				<encoding>UTF-8</encoding> 			</configuration> 		</plugin> 		<plugin> 			<groupId>org.apache.tomcat.maven</groupId> 			<artifactId>tomcat7-maven-plugin</artifactId> 			<configuration> 				<!-- 指定端口 --> 				<port>9003</port> 				<!-- 请求路径 --> 				<path>/</path> 			</configuration> 		</plugin> 	</plugins> </build>

 

2. 配置文件 springSecurity.xml 和 web.xml 添加过滤器等配置

(1) springSecurity.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="/login.html" security="none"></http>     <http pattern="/login_error.html" security="none"></http> 	     <!-- 拦截规则 -->     <http use-expressions="false">         <intercept-url pattern="/**" access="ROLE_USER"/> 		         <form-login login-page="/login.html"              default-target-url="/index.html"             authentication-failure-url="/login_error.html"/>         <csrf disabled="true"/>         <headers>             <frame-options policy="SAMEORIGIN"/>         </headers>         <logout logout-url="logout" logout-success-url="/login.html"/>     </http> 	     <!-- 认证管理器 -->     <authentication-manager>         <authentication-provider>             <user-service>                 <!-- 指定哪个用户进行登录 这种方式是写死的,应该是去数据库里查找                     authorities:指定当前用户 有哪些权限                 -->                 <user name="admin" password="admin" authorities="ROLE_USER"/>             </user-service>         </authentication-provider>     </authentication-manager> </beans:beans>

(2) web.xml 文件配置

<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">   <display-name>casclient_demo3</display-name>   <welcome-file-list>     <welcome-file>index.html</welcome-file>     <welcome-file>index.htm</welcome-file>     <welcome-file>index.jsp</welcome-file>     <welcome-file>default.html</welcome-file>     <welcome-file>default.htm</welcome-file>     <welcome-file>default.jsp</welcome-file>   </welcome-file-list>        <!-- 通过监听器 加载配置文件 -->     <context-param>         <param-name>contextConfigLocation</param-name>         <param-value>classpath:springSecurity.xml</param-value>     </context-param>     <listener>         <listener-class>              org.springframework.web.context.ContextLoaderListener         </listener-class>     </listener>	          <!-- 解决post乱码 -->     <filter>         <filter-name>CharacterEncodingFilter</filter-name>         <filter-class>             org.springframework.web.filter.CharacterEncodingFilter         </filter-class>         <init-param>             <param-name>encoding</param-name>             <param-value>utf-8</param-value>         </init-param>         <init-param>               <param-name>forceEncoding</param-name>               <param-value>true</param-value>           </init-param>       </filter>     <filter-mapping>         <filter-name>CharacterEncodingFilter</filter-name>         <url-pattern>/*</url-pattern>     </filter-mapping> 	     <!-- spring security filter -->     <filter>           <filter-name>springSecurityFilterChain</filter-name>  		         <filter-class>             org.springframework.web.filter.DelegatingFilterProxy         </filter-class>       </filter>       <filter-mapping>           <filter-name>springSecurityFilterChain</filter-name>           <url-pattern>/*</url-pattern>       </filter-mapping>	 	  	      <servlet>         <servlet-name>springmvc</servlet-name>         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>         <!-- 指定加载的配置文件 ,通过参数contextConfigLocation加载 -->         <init-param>             <param-name>contextConfigLocation</param-name>             <param-value>classpath:springmvc.xml</param-value>         </init-param>     </servlet>     <servlet-mapping>         <servlet-name>springmvc</servlet-name>         <url-pattern>*.do</url-pattern>     </servlet-mapping> </web-app>

3.创建页面

    

4. 认证类

package com.itcast.service;  import java.util.ArrayList; import java.util.List;  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; /**  * 认证类  */ public class UserDetailsServiceImpl implements UserDetailsService {  	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 		         System.out.println("经过了认证类的请求");         List<GrantedAuthority> grantAuths = new ArrayList();         grantAuths.add(new SimpleGrantedAuthority("ROLE_SELLER"));         grantAuths.add(new SimpleGrantedAuthority("ROLE_USER"));         /**          *  认证信息(角色)          *  参数:用户名 ,密码,权限集合          */         return new User(username,"",grantAuths );     } }

 

 

二、在第一步的基础上 对 CAS 进行集成

1. 添加 springsecurity 与 CAS 整合的依赖 jar 包

<!-- springsecurity 与 cas 整合的jar包 -->     <dependency>           <groupId>org.springframework.security</groupId>           <artifactId>spring-security-cas</artifactId>           <version>4.1.0.RELEASE</version>       </dependency>        <!-- CAS 核心的 jar 包 -->       <dependency>           <groupId>org.jasig.cas.client</groupId>           <artifactId>cas-client-core</artifactId>           <version>3.3.3</version>         <!-- 排除的依赖 ,以防冲突 -->         <exclusions>               <exclusion>                   <groupId>org.slf4j</groupId>                   <artifactId>log4j-over-slf4j</artifactId>               </exclusion>           </exclusions>       </dependency> 

2. 修改 springSecurity.xml 配置文件   (本项目 最最最 重要的一部分)

注意:在spring-security 与 CAS 集成以后,原本在web.xml 中要配置的一大堆的过滤器 就不需要 web.xml 文件中配置了,都放到 spring-security.xml 中进行配置。

(1) 删除原来有 security 管理的登录内容。需要删除的内容如下:

<!-- http标签中的内容 --> <form-login login-page="/login.html"      default-target-url="/index.html"     authentication-failure-url="/login_error.html"/> <headers>     <frame-options policy="SAMEORIGIN"/> </headers> <logout logout-url="logout" logout-success-url="/login.html"/>  <!-- 认证管理器 --> <authentication-manager>     <authentication-provider>         <user-service>             <!-- 指定哪个用户进行登录 这种方式是写死的,应该是去数据库里查找                 authorities:指定当前用户 有哪些权限             -->             <user name="admin" password="admin" authorities="ROLE_USER"/>         </user-service>     </authentication-provider> </authentication-manager>

(2) 既然 security 不再管理登录,那么 就需要配置 CAS 的信息 来管理登录 即:各种过滤器

    注意:这些过滤器 是一种调用关系: 认证过滤器  -->  认证管理器  -->  认证提供者(真正干活的)

    认证提供者里面包含:① 用户详细信息服务提供者(里面没有登录的信息只有权限的信息);②   票据认证器

<?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="/login.html" security="none"></http>     <http pattern="/login_error.html" security="none"></http> 	     <!-- 拦截规则 -->     <!--          entry-point-ref:切入点,登录的操作交给 CAS 操作     -->     <http use-expressions="false" entry-point-ref="casProcessingFilterEntryPoint">         <intercept-url pattern="/**" access="ROLE_USER"/>         <csrf disabled="true"/> 		         <!-- custom-filter为过滤器, position 表示将过滤器放在指定的位置上,before表示放在指定位置之前  ,after表示放在指定的位置之后  -->                    <!-- security 已经预定义好了很多过滤器,我们只需要往里面插入我们自定义的              security 不仅可以与 CAS 进行集合,还可以与第三方如微信、QQ等集合通过 oauth。         -->         <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://localhost: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:9003/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://localhost: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="com.itcast.service.UserDetailsServiceImpl"/>       <!-- 认证过滤器 结束 -->               <!-- 单点登出  开始  -->          <beans:bean id="singleLogoutFilter" class="org.jasig.cas.client.session.SingleSignOutFilter"/>               <beans:bean id="requestSingleLogoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">           <beans:constructor-arg value="http://localhost:9100/cas/logout?service=http://www.baidu.com"/>           <beans:constructor-arg>               <beans:bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>           </beans:constructor-arg>         <!-- 直接输入"/logout/cas"即可退出,代替上面service参数 -->           <beans:property name="filterProcessesUrl" value="/logout/cas"/>       </beans:bean>       <!-- 单点登出  结束 -->      </beans:beans>

 

    总结:对于不同的项目 在配置里面只需要更改四处即可

    ① 单点登录服务器登录的URL,只需要改 端口号

<beans:property name="loginUrl" value="http://localhost:9100/cas/login"/>

    ② 自己项目的路径,只需要改 端口号

<!--service 配置自身工程的根地址+/login/cas   -->   <beans:property name="service" value="http://localhost:9003/login/cas"/>

    ③ 票据认证器的地址,只需要改 端口号

<beans:constructor-arg index="0" value="http://localhost:9100/cas"/>

    ④ 单点登出的地址,只需要改 端口号 和 service 参数

<beans:constructor-arg value="http://localhost:9100/cas/logout?service=http://www.baidu.com"/>

(3) 编写一个获取登录名的 类

package com.itcast.service;  import java.util.HashMap; import java.util.Map;  import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;  /**  * 运营商登录的控制层的类  * @author jt  *  */ @RestController @RequestMapping("/login") public class LoginController {  	@RequestMapping("/showName") 	public String showName(){ //		Map map = new HashMap(); 		// 获得用户名信息: 		String username = SecurityContextHolder.getContext().getAuthentication().getName(); //		map.put("username", username); 		 		return username; 	} }

    创建springmvc.xml 配置文件

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" 	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" 	xmlns:context="http://www.springframework.org/schema/context" 	xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc" 	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd         http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd         http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">      <context:component-scan base-package="com.itcast.service" />     <mvc:annotation-driven/> </beans>

(4) 测试 运行

    启动 CAS 的服务,启动工程,地址栏:localhost:9003

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!