【试水CAS-4.0.3】第07节_CAS客户端配置单点登录

本文源码下载:http://download.csdn.net/detail/jadyer/8934207

/**
 * @see CAS客户端配置
 * @see ------------------------------------------------------------------------------------------------------------------------
 * @see 这里用的是cas-client-core-3.4.0.jar(这是2015-07-21发布的)
 * @see 下载地址http://mvnrepository.com/artifact/org.jasig.cas.client/cas-client-core/3.4.0
 * @see 另外为了使客户端在HTTP协议下单点成功,可以修改以下两处配置使其不开启HTTPS验证
 * @see 1.\WEB-INF\deployerConfigContext.xml
 * @see   <bean class="org.jasig...support.HttpBasedServiceCredentialsAuthenticationHandler">添加p:requireSecure="false"
 * @see 2.\WEB-INF\spring-configuration\ticketGrantingTicketCookieGenerator.xml和\WEB-INF\spring-configuration\warnCookieGenerator.xml
 * @see   p:cookieSecure="true"改为p:cookieSecure="false"
 * @see 下面介绍两种配置方法,一种是纯web.xml配置,一种是借助Spring来配置,相关的官方文档如下所示
 * @see https://wiki.jasig.org/display/CASC/Configuring+the+Jasig+CAS+Client+for+Java+in+the+web.xml
 * @see https://wiki.jasig.org/display/CASC/Configuring+the+JA-SIG+CAS+Client+for+Java+using+Spring
 * @see ------------------------------------------------------------------------------------------------------------------------
 * @see 纯web.xml
 * @see web.xml中需配置四个顺序固定的Filter,而且出于认证考虑,最好配置在其他Filter之前,它们的先后顺序如下
 * @see AuthenticationFilter
 * @see TicketValidationFilter(或其它AbstractTicketValidationFilter实现,比如Cas20ProxyReceivingTicketValidationFilter)
 * @see HttpServletRequestWrapperFilter
 * @see AssertionThreadLocalFilter
 * @see 另外各个Filter的<init-param>优先级都比<context-param>要高,通常<context-param>用来配置公用的参数
 * @see 1.AuthenticationFilter
 * @see   用来拦截请求,判断是否需要CASServer认证,需要则跳转到CASServer登录页,否则放行请求
 * @see   有两个必须参数,一个是指定CASServer登录地址的casServerLoginUrl,另一个是指定认证成功后跳转地址的serverName或service
 * @see   service和serverName设置一个即可,二者都设置时service的优先级更高,即会以service为准
 * @see   service指的是一个确切的URL,而serverName是用来指定客户端的主机名的,格式为{protocol}:{hostName}:{port}
 * @see   指定serverName时,该Filter会把它附加上当前请求的URI及对应的查询参数来构造一个确切的URL作为认证成功后的跳转地址
 * @see   比如serverName为"http://gg.cn",当前请求的URI为"/oa",查询参数为"aa=bb",则认证成功后跳转地址为http://gg.cn/oa?aa=bb
 * @see   casServerLoginUrl--去哪登录,serverName--我是谁
 * @see 2.TicketValidationFilter
 * @see   请求通过AuthenticationFilter认证后,若请求中携带了ticket参数,则会由该类Filter对携带的ticket进行校验
 * @see   验证ticket的时候,要访问CAS服务的/serviceValidate接口,使用的url就是${casServerUrlPrefix}/serviceValidate
 * @see   所以它也有两个参数是必须指定的,casServerUrlPrefix(CASServer对应URL地址的前缀)和serverName或service
 * @see   实际上,TicketValidationFilter只是对验证ticket的这一类Filter的统称,其并不对应CASClient中的具体类型
 * @see   CASClient中有多种验证ticket的Filter,都继承自AbstractTicketValidationFilter
 * @see   常见的有Cas10TicketValidationFilter/Cas20ProxyReceivingTicketValidationFilter/Saml11TicketValidationFilter
 * @see   它们的验证逻辑都是一致的,都有AbstractTicketValidationFilter实现,只是使用的TicketValidator不一样而已
 * @see 3.HttpServletRequestWrapperFilter
 * @see   用于封装每个请求的HttpServletRequest为其内部定义的CasHttpServletRequestWrapper
 * @see   它会将保存在Session或request中的Assertion对象重写HttpServletRequest的getUserPrincipal()、getRemoteUser()、isUserInRole()
 * @see   这样在我们的应用中就可以非常方便的从HttpServletRequest中获取到用户的相关信息
 * @see 4.AssertionThreadLocalFilter
 * @see   为了方便用户在应用的其它地方获取Assertion对象,其会将当前的Assertion对象存放到当前的线程变量中
 * @see   以后用户在程序的任何地方都可以从线程变量中获取当前的Assertion,而无需从Session或request中解析
 * @see   该线程变量是由AssertionHolder持有的,我们在获取当前的Assertion时也只需Assertion assertion = AssertionHolder.getAssertion()
 * @see ------------------------------------------------------------------------------------------------------------------------
 * @see 借助Spring
 * @see 与上述web.xml配置四个Filter方式不同的是,可以使用Spring的四个DelegatingFilterProxy来代理需要配置的四个Filter
 * @see 此时这四个Filter就应该配置为Spring的Bean对象,并且web.xml中的<filter-name>就应该对应SpringBean名称
 * @see 但是SingleSignOutFilter/HttpServletRequestWrapperFilter/AssertionThreadLocalFilter等Filter不含配置参数
 * @see 所以实际上只需要配置AuthenticationFilter和Cas20ProxyReceivingTicketValidationFilter两个Filter交由Spring代理就可以了
 * @see ------------------------------------------------------------------------------------------------------------------------
 * @see 注意
 * @see 1.CAS1.0提供的接口有/validate,CAS2.0提供的接口有/serviceValidate,/proxyValidate,/proxy
 * @see 2.四个Filter太多了,有时间的话考虑参考org.springframework.web.filter.CompositeFilter写一个Filter来实现
 * @see 3.web.xml的好处是可以配置匿名访问的资源,配置参数参考AuthenticationFilter中的ignoreUrlPatternMatcherStrategyClass
 * @see   起码cas-client-core-3.4.0.jar中的Spring配置还不支持ignorePattern(该参数默认正则验证,此外还有contains和equals验证)
 * @see 4.javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No name matching casserver found
 * @see   这是由于创建证书的域名和应用中配置的CAS服务域名不一致导致出错(说白了就是指客户端导入的CRT证书与CAS服务端的域名不同)
 * @see ------------------------------------------------------------------------------------------------------------------------
 * @create 2015-7-26 下午1:00:14
 * @author 玄玉<http://blog.csdn.net/jadyer>
 */

下面是web.xml的配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:applicationContext.xml</param-value>
	</context-param>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<servlet>
		<servlet-name>SpringMVC</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:applicationContext.xml</param-value>
		</init-param>
	</servlet>
	<servlet-mapping>
		<servlet-name>SpringMVC</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

	<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>

	<!-- SSO -->
	<filter>
		<filter-name>casAuthenticationFilter</filter-name>
		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>casAuthenticationFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<filter>
		<filter-name>casTicketValidationFilter</filter-name>
		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>casTicketValidationFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<!--
	<context-param>
		<param-name>serverName</param-name>
		<param-value>http://boss.jadyer.com:8080</param-value>
	</context-param>
	<filter>
		<filter-name>casAuthenticationFilter</filter-name>
		<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
		<init-param>
			<param-name>casServerLoginUrl</param-name>
			<param-value>http://sso.jadyer.com:8080/cas-server-web/login</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>casAuthenticationFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<filter>
		<filter-name>casTicketValidationFilter</filter-name>
		<filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
		<init-param>
			<param-name>casServerUrlPrefix</param-name>
			<param-value>http://sso.jadyer.com:8080/cas-server-web</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>casTicketValidationFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	 -->
	<filter>
		<filter-name>casHttpServletRequestWrapperFilter</filter-name>
		<filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>casHttpServletRequestWrapperFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<filter>
		<filter-name>casAssertionThreadLocalFilter</filter-name>
		<filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>casAssertionThreadLocalFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
</web-app>

下面是//src//applicationContext.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:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
						http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
						http://www.springframework.org/schema/mvc
						http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
	<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
		<property name="ignoreResourceNotFound" value="false"/>
		<property name="locations">
			<list>
				<value>classpath:config.properties</value>
			</list>
		</property>
	</bean>
	<mvc:resources mapping="/index.jsp" location="/index.jsp"/>

	<!-- cas -->
	<bean name="casAuthenticationFilter" class="org.jasig.cas.client.authentication.AuthenticationFilter">
		<property name="serverName" value="${casClientServerName}"/>
		<property name="casServerLoginUrl" value="${casServerLoginUrl}"/>
	</bean>
	<bean name="casTicketValidationFilter" class="org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter">
		<property name="serverName" value="${casClientServerName}"/>
		<property name="ticketValidator">
			<bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
				<constructor-arg index="0" value="${casServerUrlPrefix}"/>
			</bean>
		</property>
	</bean>
</beans>

下面是//src//config.properties

#<<Central Authentication Service>>
#where to login
casServerLoginUrl=http://sso.jadyer.com:8080/cas-server-web/login
#login server root
casServerUrlPrefix=http://sso.jadyer.com:8080/cas-server-web
#who am i
casClientServerName=http://boss.jadyer.com:8080

最后是//WebRoot//index.jsp

<%@ page pageEncoding="UTF-8"%>
<%@ page import="java.util.Map"%>
<%@ page import="java.net.URLDecoder"%>
<%@ page import="org.jasig.cas.client.util.AssertionHolder"%>
<%@ page import="org.jasig.cas.client.authentication.AttributePrincipal"%>

<body style="background-color:#CBE0C9;">
	<span style="color:red; font-size:32px; font-weight:bold;">客户端登录成功</span>
</body>

<hr size="2">

<%
	AttributePrincipal principal = (AttributePrincipal)request.getUserPrincipal();
	Map<String, Object> attributes = principal.getAttributes();
	out.print("principal.getName()=" + principal.getName() + "<br/>");
	out.print("request.getRemoteUser()=" + request.getRemoteUser() + "<br/>");
	out.print("登录用户:" + attributes.get("userId") + "<br/>");
	out.print("登录时间:" + AssertionHolder.getAssertion().getAuthenticationDate() + "<br/>");
	out.print("-----------------------------------------------------------------------<br/>");
	for(Map.Entry<String,Object> entry : attributes.entrySet()){
		//服务端返回中文时需要encode,客户端接收显示中文时需要decode,否则会乱码
		out.print(entry.getKey() + "=" + URLDecoder.decode(entry.getValue().toString(), "UTF-8") + "<br/>");
	}
	out.print("-----------------------------------------------------------------------<br/>");
	Map<String, Object> attributes22 = AssertionHolder.getAssertion().getAttributes();
	for(Map.Entry<String,Object> entry : attributes22.entrySet()){
		out.print(entry.getKey() + "=" + entry.getValue() + "<br/>");
	}
	out.print("-----------------------------------------------------------------------<br/>");
	Map<String, Object> attributes33 = AssertionHolder.getAssertion().getPrincipal().getAttributes();
	for(Map.Entry<String,Object> entry : attributes33.entrySet()){
		out.print(entry.getKey() + "=" + entry.getValue() + "<br/>");
	}
%>

接下来就可以测试了,测试之前先修改几处配置,模拟单点环境

/**
 * @see ------------------------------------------------------------------------------------------------------------------------
 * @see 测试时在C:\Windows\System32\drivers\etc\hosts中添加以下三个配置
 * @see 127.0.0.1 sso.jadyer.com
 * @see 127.0.0.1 boss.jadyer.com
 * @see 127.0.0.1 risk.jadyer.com
 * @see ------------------------------------------------------------------------------------------------------------------------
 * @see 然后拷贝三个Tomcat,分别用作sso服务器和两个sso客户端
 * @see 修改两个sso客户端的\Tomcat\conf\server.xml的以下三个端口,保证启动监听端口不重复
 * @see <Server port="8105" shutdown="SHUTDOWN">
 * @see <Connector port="8180" protocol="HTTP/1.1"......>
 * @see <Connector port="8109" protocol="AJP/1.3" redirectPort="8443" />
 * @see <Server port="8205" shutdown="SHUTDOWN">
 * @see <Connector port="8280" protocol="HTTP/1.1"......>
 * @see <Connector port="8209" protocol="AJP/1.3" redirectPort="8443" />
 * @see ------------------------------------------------------------------------------------------------------------------------
 * @see 最后修改两个sso客户端的\Tomcat\webapps\cas-client\WEB-INF\classes\config.properties的casClientServerName值
 * @see casClientServerName=http://boss.jadyer.com:8180
 * @see casClientServerName=http://risk.jadyer.com:8280
 * @see ------------------------------------------------------------------------------------------------------------------------
 * @create 2015-7-26 下午1:08:35
 * @author 玄玉<http://blog.csdn.net/jadyer>
 */

现在开始测试

先访问http://boss.jadyer.com:8180/cas-client,发现没登录会自动跳转到单点登录页

输入密码后登录成功

再访问http://risk.jadyer.com:8280/cas-client,会发现自动登录成功,不用再登录了

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-06 03:48:11

【试水CAS-4.0.3】第07节_CAS客户端配置单点登录的相关文章

【试水CAS-4.0.3】第08节_CAS客户端配置单点登出

本文内容包括配置单点登出.登出后自动跳转指定资源.CASServer禁用单点登出等 /** * @see ------------------------------------------------------------------------------------------------------------------------ * @see CAS客户端配置单点登出 * @see 与单点登录相对应,通过CASServer登出所有的CASClient,登录的URL是/login,

2、cas4.0 单点登录 之 cas-client

cas4.0 单点登录 之 cas-client cas4.0 单点登录 之 https证书已经做好了证书的准备工作,现在结合cas-server来配置单点登录: 一.安装cas服务端(cas-server) cas服务端是一个war包,这里只做体验单点登录,cas-server下载点这里cas-server-webapp-4.0.0.war,将war包放tomcat下运行即可,运行cas-server的tomcat的要开启SSL支持,上面文章也有说明,server.xml需要如下配置: <Co

SSO 基于CAS实现单点登录 实例解析(二)

本文目录: 概述 演示环境 部署CAS-Server相关的Tomcat 部署CAS-Client相关的Tomcat 测试验证SSO 第一: 本demo在一个机器上实现(三个虚拟主机),来看SSO单点登录实例(我们可以布到多个机器上使用都是同一个道理的),一个服务器主机,和两个客户端虚拟主机 <span style="font-size:18px;"># 127.0.0.1 localhost # ::1 localhost 127.0.0.1 localhost 127.0

使用 CAS 在 Tomcat 中实现单点登录

单点登录(Single Sign On , 简称 SSO )是目前比较流行的服务于企业业务整合的解决方案之一, SSO 使得在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统.CAS(Central Authentication Service)是一款不错的针对 Web 应用的单点登录框架,本文介绍了 CAS 的原理.协议.在 Tomcat 中的配置和使用,对于采用 CAS 实现轻量级单点登录解决方案的入门读者具有一定指导作用. CAS 介绍 CAS 是 Yale 大学发起的一

Jeesite单点登录集成cas另加自定义登录验证

Jeesite单点登录集成Cas另加自定义登录验证 JeeSite是基于多个优秀的开源项目,高度整合封装而成的高效,高性能,强安全性的 开源 Java EE快速开发平台. Cas主要是用来解决多应用之间统一登陆认证,无需用户在同一公司多应用之间重复登陆.例如阿里巴巴中淘宝.天猫,在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统. Cas基础 服务端 服务端cas-server-webapp-4.0.0.war,服务器端程序一般不用我们完成,但需要做一点小小的修改,cas的服务

SSO之CAS单点登录详细搭建教程

本教程是我个人编写,花费几个小时的时间,给需要学习的人员学习使用,希望能帮助到你们. [环境说明]:本文演示过程在同一个机器上的(也可以在三台实体机器或者三个的虚拟机上),环境如下: windows7 64位 jdk1.7.0_51 apache-tomcat-7.0.57-windows-x64 cas-server-webapp-4.0.0.war.cas-client-core-3.2.1.jar.commons-logging.jar 确保本地jdk环境已经搭建好 [软件说明]:文档中涉

CAS Server实现单点登录(Single Sign On , 简称 SSO )

一.什么是单点登录.二.利用耶鲁大学的开源项目CAS(Central Authentication Service),搭建基于JavaWeb项目的单点登录.三.针对具体项目对CAS做二次开发以适用具体的业务. 一.什么是单点登录.     单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一.SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统.     当用户第一次访问应用系统的时候,因为还没有登录,会被引导到认证系

单点登录系统CAS入门

一.单点登录的概念 单点登录(Single Sign On),简称为SSO.SSO是定义在多个应用系统中,用户只需要登录一次就可以访问所有的相互信任的应用系统. 当我们创建工程的子系统部署在不同的服务中的时候,使用传统的session是无法解决问题的,这时候我们就需要使用相关的单点登录技术来解决. 1.CAS概述 CAS是Yale大学的一个开源项目,旨在为web应用系统提供一种可靠的单点登录方法.CAS具有以下特点: 开源的企业级单点登录解决方案 CAS Server为需要独立部署的Web应用

Mvc4单点登录之一Cas简单介绍

背景 前几天写过一篇博客Net单点登录详解 (SSO),但是在这篇博客中是在asp.net 下做的实验,没有什么问题,但是转换到mvc中之后,问题就接二连三的出,后来没有办法,想想还是用人家已经写好的吧,别用那些自己写的东西了,一是不稳定,二是有很多的缺陷!然后就开始寻找!最后决定用cas来做! SSO介绍 SSO英文全称SingleSign On,单点登录.SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统. CAS = CentralAuthentication S