基于CAS的SSO实践
本人小白一枚,借鉴网上大牛们的经验,实现了基于CAS的SSO单点登录功能,一步一个脚印,一个脚印一个坑,好在最后实现。(后附参考文献,不分先后)
【演示环境】
1.jdk-7u67-windows-x64.exe(最好只装一个版本的jdk,避免出现意外错误)
2.apache-tomcat-7.0.76.zip(非安装版)
3.cas-server-4.0.0-release.zip(cas服务端)
4.cas-client-3.2.0-release.zip(cas客户端)
【环境说明1】
修改hosts文件添加域名,C:\Windows\System32\drivers\etc\hosts 在文件末端添加下面三条信息:
127.0.0.1 sso.server.com(对应部署casserver的tomcat)
127.0.0.1 sso.client1.com(对应部署cas client1的tomcat)
127.0.0.1 sso.client2.com(对应部署cas client2的tomcat)
【注意】 这个非常重要,因为CAS单点登录系统是基于JAVA安全证书的https协议,要使用CAS单点登录必须要配置域名, cas server是不能通过ip访问的。
上面3个ip都是127.0.0.1,这是因为我的环境都是在同一台机器,所以ip都是一致的。一个域名对应一个应用,模拟多端。
C:\Windows\System32\drivers\etc\hosts以记事本格式打开,该文件用于IP地址与主机名的对应,每条对应单独一行,以”#”标示机器名(machine name)。每行起始的#是注释意思,
【环境说明2】
安全证书配置阶段需要提前配置好java环境,可以官网下载jdk-7u67-windows-x64.exe。jdk-7u67-windows-x64.exe安装成功后需要对JDK环境变量进行配置,见图1、图2,开始->控制面板->更改设置
图1 新建系统变量JAVA_HOME
在系统变量里新建JAVA_HOME,值就是该 jdk-7u67-windows-x64.exe的安装位置,这些配置会在后面生成、导出、导入证书,启动Tomcat,反复使用,所以变量值不要太长,否则后面在cmd中反复输入该路径,会烦到怀疑人生。
那么,怎么设置一个较短的值呢?Java前不要太长,就像我这样即可。
图2 设置JAVA_HOME变量值
【安全证书配置】
说明
本教程目的在于演示,所以使用JDK自带的keytool工具生成证书。如若在产品环境中使用,需要向证书提供商购买,证书认证一般由 VeriSign认证,中文官方网站: http://www.verisign.com/cn/。
本教程全部取自实操环境,由于报错与调试迭代原因,存在图片截取时间前后不一致情况,但是不影响整个工程实现,直接参考图片操作部分即可。
1>.打开cmd命令窗口(管理员身份打开)
开始—>cmd—>右键选择“以管理员身份运行”
cd到C盘根目录或者是jdk的bin目录下,
cd C:\Program Files\Java\jdk1.7.0_80\bin 回车,进入java运行,见图3。
图3 进入java运行
2>.生成证书,在java运行环境的cmd窗口输入以下命令:
keytool -genkey -alias ssodemo -keyalg RSA -keysize 2048 -keypass 123456 -validity 365 -keystore c:\wsriakey -storepass 123456
以上命令的执行会在c:\目录下自动新建一个名为wsriakey的文件(证书库)。
可以通过以下命令查看记录于其中的证书内容,
keytool –list –v –alias ssodemo –keystore c:\wriaskey –storepass 123456
该命令意味着查询位于c:\的wsriakey证书库文件中,别名为ssodemo的证书记录。见图4。
图4 证书库wriaskey中别名为ssodemo的证书记录
说明
这段命令的意思是:生成一个证书,别名是ssodemo,采用非对称加密算法RSA,**长度2048位,该证书有效期365天,存放在c:\wsriakey并命名为wsriakey,存储密码为123456。
keytool 是jdk提供的工具,该工具名为”keytool“。
-genkey:创建证书。
-alias:证书的别名,可以自定义。在一个证书库文件中,别名是唯一用来区分多个证书的标识符。
-keyalg:**的算法,可以选择的**算法有:RSA、DSA、EC。
keyalg=RSA时,签名算法有:MD5withRSA、SHA1withRSA、SHA256withRSA、SHA384withRSA、SHA512withRSA。keyalg=DSA时,签名算法有:SHA1withDSA、SHA256withDSA。此处需要注意:MD5和SHA1的签名算法已经不安全。
-keystore:证书库()文件保存的位置和文件(证书库)名。如果路径写错的话,会出现报错信息。如果在路径下,证书库文件不存在,那么就会创建一个。
-keysize:**长度,keysize与keyalg存在默认对应关系,其中:
2048 (when using -genkeypair and -keyalg is “RSA”),
1024 (when using -genkeypair and -keyalg is “DSA”),
256 (when using -genkeypair and -keyalg is “EC”)。
-validity:证书的有效期,单位天。比如36500就是100年
-keypass password (用来access the particular key pair's private key)此处”password “为本条目的密码(私钥的密码)。最好与storepass一致。
-storepass mypassword (用来access the key store)此处”mypassword “为证书库密码(私钥的密码)。最好与keypass 一致
-storetype JKS 此处”JKS “为证书库类型。可用的证书库类型为:JKS、PKCS12等。jdk9以前,默认为JKS。自jdk9开始,默认为PKCS12。
CN= 名字与姓氏/域名,本实例填写sso.server.com
OU= 组织单位名称, 本实例填写server.com
O= 组织名称, 本实例填写ssodemo
L= 城市或区域名称, 本实例填写tianjin
ST= 州或省份名称, 本实例填写tianjin
C= 单位的两字母国家代码, 本实例填写CN
必须输入在C:\Windows\System32\drivers\etc\hosts文件中加入的服务端的域,本实例CN=sso.server.com,为何这么做?
首先cas只能通过域名来访问,不能通过ip访问;其次,由于上方是要求比较严格的证书生成,如果不这么做的话,即使最终按照教程配置完成,cas也可以正常访问,访问一个客户端应用也能进入cas验证首页,但是,当输入信息正确后,cas在回调转入你想访问的客户端应用的时候,会出现No subject alternative names present错误异常信息,这个错误就是由CN输入不是域名导致,或者与hosts文件配置的不一致导致。
在C:\目录下得到一个wsriakey的(证书库)文件,见图5。
图5 c:\目录下得到一个wsriakey的(证书库)文件
如果继续向同一证书库生成同一别名的证书,会报错,见图6,
图6 证书库中证书别名不能冲突
3>.导出证书(根据私钥导出服务端证书):
在cmd窗口继续输入以下命令,导出证书:
keytool -export -alias ssodemo -keystore c:\wsriakey -file c:\wsria.crt -storepass 123456
说明
-alias后面的名称要与生成证书的命令里面的alias的名称一致; –keystore指定证书存放的位置,本实例放在C盘根目录,同时证书名称要与”生成证书”对应的命令里的keystore名称一致,这里是wsriakey;-file指定导出证书的路径(crt路径),本实例也指定在c盘根目录;-storepass的证书密码要与上面输入的密码一致。
该命令意思是,将生成在在证书库c:\wsriakey中别名为ssodemo的证书记录(**对),导出到“c:\ ”,并命名为wsria.crt证书,其中,-storepass即为生成证书时的证书库访问密码。见图7 证书导出。
图7 证书导出
4>.导入证书(客户端导入证书):
keytool -import -keystore %JAVA_HOME%\jre\lib\security\cacerts -file c:\wsria.crt -alias ssodemo
说明
命令中指定了JAVA_HOME,意思是将证书导入到客户端证书库,也就是jdk证书库中,因为客户端应用运行在本地,需要jdk的支持。-file指已生成导出的证书的位置和证书名,也就是上一步导出(-export)证书的位置,即c:\wsria.crt。%JAVA_HOME%指证书库cacerts的绝对路径,可以用“c:\program files\java\jdk1.7.0_80\jre\lib\security\cacerts”(记得命令输入时带双引号),也可以用$JAVA_HOME\ jre\lib\security\cacerts(此时不用接双引号)。
该命令的意思是,将位于C:\的证书wsria.crt中别名为ssodemo的证书记录导入JDK位于C:\program files\java\jdk1.7.0_80\jre\lib\security\cacerts的cacerts证书库中,别名为ssodemo的合法证书在该证书库中以条目的形式记录(个人认为存储了**对等内容,详情可以通过-v –list查看)。见图8、图9,并附带带密码导入和不带密码导入2种形式,说明keytool 命令还是很灵活的。
参数说明
变量名"JAVA_HOME",
变量值"C:\Program File\Java jdk1.7.0_80":JDK的安装路径
%JAVA_HOME%\jre:运行环境所在位置
cacerts:证书库
图8 –import 命令形式1
图9 –import 命令形式2
回车之后,会让你输入**库口令,注意,这里的密码必须要输入changeit(这个是该jdk证书库默认密码),不能输入上面指定的密码123456,切记,否则导入客户端证书会有问题。
如果是多台机器演示,需要在每一台客户端导入该证书,步骤都是一样的。当看到提示“是否信任此证书”,输入y回车即可,见下图:(说明,命令中的-alias后面的别名可以自定义,如果出现”证书未导入,别名<***>已经存在”的错误,该意思是说客户端的**库中已经存在该别名证书了,重新指定其他别名即可)。
观察jdk中证书库修改时间因为导入别名为ssodemo的证书条目而更新变化(图10)。
图10 jdk中证书库修改时间因为导入别名为ssodemo的证书条目而更新变化
至此,CAS所需的证书环境,已经配置好。
下面,开始CAS服务、Tomcat、以及多客户端()的配置及测试访问。
【部署CAS-Server以及配置Tomcat】
1>.配置HTTPS
由于CAS是基于HTTPS协议,所以需要配置服务端的tomcat,使之支持SSL安全协议访问。
解压apache-tomcat-7.0.76-windows-x64.zip,缩短路径,更改文件名(原因与JAVA_HOME缩短路径名相同),本实例的本地路径为c:\program files\apache-tomcat,编辑C:\program files\apache-tomcat\conf\server.xml,找到下面片段去掉注释,修改成:
<Connectorport="8443" protocol="org.apache.coyote.http11.Http11Protocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
keystoreFile="C:/wsriakey" keystorePass="123456"
clientAuth="false" sslProtocol="TLS"/>
其中,keystoreFile就是创建证书的路径,keystorePass就是创建证书的密码。
2>.验证HTTPS配置
其他按照默认配置不作修改,双击C:\program files\apache-tomcat\bin\startup.bat启动tomcat ,或者cmd输入见图11、图12。
图11 使用命令行启动tomcat
图12 启动tomcat-server
验证https是否配置成功:本案例本地使用google览器访问(似乎IE不好使),在地址栏输入https://sso.server.com:8443/出现下面画面,其实这就表明cas服务端tomcat的https协议配置没问题了。
成功,见图13。
图13 https配置成功
点击【高级】,点击出现的【继续前往sso.server.com(不安全)】,将会出现图14tomcat默认首页,表明tomcat已经支持https协议访问了,一切ok。
图14 tomcat已经支持https协议访问
3>.部署CAS-Server
CAS-Server下载地址http://developer.jasig.org/cas/,本案例使用最高版本4.0.0。想要下载最新版本,见官网http://www.jasig.org/cas/download
本案例以cas-server-4.0.0-release.zip为例,解压cas-server-4.0.0-release.zip到cas-server-4.0.0\modules里提取cas-server-webapp-4.0.0.war文件,把文件copy到C:program files\apache-tomcat\webapps目下,并重命名为cas.war。
图15 重命名cas.war
启动tomcat,在地址栏入https://sso.server.com:8443/cas/login 回车,出现CAS服务端的登录验证首页,见图16。
图16 CAS服务端的登录验证首页
调整登录页面,见图17。
图17 调整登录页面
此时,CAS只是单独运行,至于登录的用户名和密码是什么,可以查看c:program files\apache-tomcat\webapps\cas\WEB-INF \deployerConfigContext.xml文件中有这样一段配置:
<bean id="primaryAuthenticationHandler" class="org.jasig.cas.authentication.AcceptUsersAuthenticationHandler">
<property name="users">
<map>
<entry key="casuser" value="Mellon"/>
</map>
</property>
</bean>
该配置是默认静态配置用户名和密码,就可以在浏览器的CAS服务的登录框中输入用户名casuser和密码Mellon,登录看看效果,就会出现验证成功的页面,见图18。
也可以在文件中自己配置自己的用户名和密码。
图18 该页面说明CAS-Server已经部署成功
用户名和密码肯定需要和数据库进行交互验证的,该如何配置呢?
【说明】该案例本地使用的是MySQL数据库。
首先进行MySQL安装前的系统更新、环境配置。
windows系统更新超级麻烦,跟套娃一样,找到A更新,说当前不支持更新,需要先安装B更新,下载了B更新,又说要再先更新C,后面跟着DEFGHIJK……,最大的一个系统更新直接把我推回去睡觉了,躺床上还想会不会中间多个系统重启需要windows密码,第二天早上过来一看,竟然更新成功,后面就真的很顺畅呢。
感谢CSDN上一篇博文https://blog.csdn.net/huqiao1206/article/details/50768481,要不就放弃了。
图19 windows系统更新部分截图
1、准备几个需要放在CAS服务的lib目录下的jar文件(数据源为MySQL的话,这2个jar缺一不可):
mysql-connector-java-5.0.8.jar
cas-server-support-jdbc-4.0.0.jar
将这2个jar放到C:program files\apache-tomcat\webapps \cas\WEB-INF\lib。
据说” cas-server-support-jdbc-4.0.0.jar “在”cas-server-4.0.0-release.zip “的modules文件有,我是官网直接下的。
2、修改配置,支持mysql数据库交互验证。编辑C:program files\apache-tomcat\webapps \cas\WEB-INF\deployerConfigContext.xml文件,找到有这样一段配置:
注释掉第二个entry配置,最终配置如下:
<constructor-arg>
<map>
<entrykey-ref="proxyAuthenticationHandler" value-ref="proxyPrincipalResolver"/>
<!--注释这个-->
<!--<entrykey-ref="primaryAuthenticationHandler"value-ref="primaryPrincipalResolver" />-->
<!-- key-ref指定自己的本地数据库访问 -->
<entrykey-ref="dbAuthHandler" value-ref="primaryPrincipalResolver"/>
</map>
</constructor-arg>
然后再在这个xml中新加入2个bean配置,如下:
<!-- 指定数据源 -->
<bean id="dataSource"class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<propertyname="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/cas?useUnicode=true&characterEncoding=utf-8&useLocalSessionState=true"/>
<property name="username"value="root" />
<property name="password"value="root" />
</bean>
<!-- 访问本地数据库 -->
<bean id="dbAuthHandler"
class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler"
p:dataSource-ref="dataSource"
p:sql="select password from t_sys_users where userName=?"/>
其中,sql语句的意思就是,根据用户名获取密码,CAS会根据你页面输入的用户名获取该用户密码,和你输入的密码进行校验,来判断输入是否正确。Sql中的表换成你自己本地的表即可,只要根据用户名查询密码即可。
至此,CAS与数据库交互验证的配置已经配置完成,可以重新访问CAS,输入数据库中存在的用户名和密码,来看看效果如何,如果登录成功,说明配置无误。否则,请耐心检查配置是否有问题,jar包是否缺少。
服务安装成功之后通过命令net start mysql启动MySQL的服务。
现在,CAS已经支持数据库交互验证了,服务端tomcat也支持HTTPS协议访问。
下一步将搭建客户端,实现多个客户端的单点登录。
案例中本地只使用2个tomcat客户端(代表2个应用)来测试,已经满足单点登录的要求。
【部署CAS-client以及Tomcat的配置】
CAS-client下载地址:http://developer.jasig.org/cas-clients/
首先,客户端应用是要和CAS服务端进行交互的,所以这里需要jar文件放在客户端应用的lib目录下。分别是:cas-client-core-3.3.3.jar、commons-logging.jar。
cas-client-core-3.3.3.jar在CSDN花了12积分买了个,官网没有。不知作者收到钱没。
本实操案例直接使用tomcat默认自带的 webapps\examples作为演示的简单web项目。
本案例使用2个tomcat做为客户端服务器代替2个客户端应用。本地解压了2份tomcat-client作为客户端服务器,并重新命名,本地路径分别为C:program files\apache-tomcat-client1和C:program files\apache-tomcat-client2
首先,将上面2个jar分别放到
C:program files\apache-tomcat-client1\webapps\examples\WEB-INF\lib目录下,
C:program files\apache-tomcat-client2\webapps\examples\WEB-INF\lib目录下。
同时,由于在一台机子上同时启动多个tomcat容易发生端口冲突,修改cas-client1和cas-client2对应的tomcat端口号。
配置apache-tomcat-client1客户端
编辑C:program files \apache-tomcat-client1\conf\server.xml文件,找到如下3处内容:
1、port改成:18005
2、port改成:18080
3、port改成:18009
然后启动这个tomcat,即运行C:program files \apache-tomcat-client1\bin\startup.bat,如果启动窗口中没有出现错误,说明端口配置无误。请记住你配置的端口号。
浏览器输入:
http://sso.client1.com:18080/examples/servlets/servlet/HelloWorldExample,请注意”sso.client1.com”域名,就是教程一开始需要配置的C:\Windows\System32\drivers\etc\hosts的域名,用于不同的客户端域名访问,回车:
地址栏大小写要对应,见图20。
图20 apache-tomcat-client1的基本安装配置已经成功
看到上述内容表示apache-tomcat-client1的基本安装配置已经成功。
接下来需要配置最重要的内容,让客户端应用和CAS服务连接。
编辑C:program files\apache-tomcat-client1\webapps\examples\WEB-INF\web.xml,在最下面加入如下配置:
<!-- ??????,??????????????,????-->
<listener>
<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>
<!-- ??????????????,???? -->
<filter>
<filter-name>CAS Single Sign Out Filter</filter-name>
<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CAS Single Sign Out Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>CAS Filter</filter-name>
<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
<init-param>
<param-name>casServerLoginUrl</param-name>
<param-value>https://sso.server.com:8443/cas/login</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://sso.client1.com:18080</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- ???????Ticket?????,????? -->
<filter>
<filter-name>CAS Validation Filter</filter-name>
<filter-class>org.jasig.cas.client.validation.Cas10TicketValidationFilter</filter-class>
<init-param>
<param-name>casServerUrlPrefix</param-name>
<param-value>https://sso.server.com:8443/cas</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://sso.client1.com:18080</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Validation Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--
????????HttpServletRequest?????,?????????HttpServletRequest?getRemoteUser()????SSO????????,?????
-->
<filter>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--
?????????????org.jasig.cas.client.util.AssertionHolder????????????AssertionHolder.getAssertion().getPrincipal().getName()?
-->
<filter>
<filter-name>CAS Assertion Thread Local Filter</filter-name>
<filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CAS Assertion Thread Local Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
配置完成后,启动CAS服务端tomcat,再启动该客户端1的tomcat(tomcat-client1),在浏览器访问:http://sso.client1.com:18080/examples/servlets/servlet/HelloWorldExample看看是否跳转到了CAS认证界面,回车之后,见图19
图19 跳转到了CAS认证界面
图20 认证的重定向
仔细观察会发现浏览器的地址栏中,URL信息是这样的:
https://sso.server.com:8443/cas/login?service=http%3A%2F%2Fsso.client1.com%3A18080%2Fexamples%2Fservlets%2Fservlet%2FHelloWorldExample
原理,由于访客没有登录CAS认证系统,CAS认证系统拦截到访问的客户端应用,首先重定向进入到认证系统登录界面,同时URL后面加*客想访问的地址信息,当访客登录成功后,CAS服务会转向到访客刚刚访问的地址,也就是图21。
图21 认证通过重定向回到刚刚的访问地址
http://sso.client1.com:18080/examples/servlets/servlet/HelloWorldExample
转向到这个地址之后,浏览器会显示如图22
图22 浏览器地址栏COOKIE机制
上面这个内容,显示的就是你访问tomcat中的examples项目的一个servlet的返回结果。
这里,如果你够细心的话,你会发现浏览器地址栏又多了一个内容,即多了一个jsessionid参数,这个就是CAS认证的原理所在,使用的是COOKIE机制。
此处延伸一下:CAS Client 与受保护的客户端应用部署在一起,以 Filter 方式保护受保护的资源。对于访问受保护资源的每个 Web 请求,CAS Client 会分析该请求的 Http 请求中是否包含 Service Ticket,如果没有,则说明当前用户尚未登录,于是将请求重定向到指定好的 CAS Server 登录地址,并传递 Service (也就是要访问的目的资源地址),以便登录成功过后转回该地址。用户在第 3 步中输入认证信息,如果登录成功,CAS Server 随机产生一个相当长度、唯一、不可伪造的 Service Ticket,并缓存以待将来验证,之后系统自动重定向到 Service 所在地址,并为客户端浏览器设置一个 Ticket Granted Cookie(TGC),CAS Client 在拿到 Service 和新产生的 Ticket 过后,在第 5,6 步中与 CAS Server 进行身份核实,以确保 Service Ticket 的合法性。
配置apache-tomcat-client2客户端:
配置与上面的客户端(client1)配置步骤相同,其中需要注意的就是,这第二个客户端的tomcat端口要与上面的客户端以及CAS服务端的端口不一样,否则出现端口占用的错误。
步骤与相关文件参照client1,主要配置如下(此处血泪推荐,直接copy“ apache-tomcat-client1”文件夹,直接更改其中相应端口等即可,本人在此还是手动修改各个端口,添加各种.jar,增删代码,最后登录时,浏览器报错404 examples\servlets\servlet\HelloWorldExample,看样子是找不到这个路径,但是就是无法纠错,如果有人能解惑,请赐教。最后还是采取整体copy文件夹,小部分修改的方式实现了):
1、port改成:28005
2、port改成:28080
3、port改成:28009
修改编辑C:program files\apache-tomcat-client2\webapps\examples\WEB-INF\web.xml文件,加入的内容与上面第一个客户端的web.xml内容一致,只不过需要修改2处内容,就是2个客户端url地址,最终的配置如下:
<!-- ??????,??????????????,????-->
<listener>
<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>
<!-- ??????????????,???? -->
<filter>
<filter-name>CAS Single Sign Out Filter</filter-name>
<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CAS Single Sign Out Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>CAS Filter</filter-name>
<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
<init-param>
<param-name>casServerLoginUrl</param-name>
<param-value>https://sso.server.com:8443/cas/login</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://sso.client2.com:28080</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- ???????Ticket?????,????? -->
<filter>
<filter-name>CAS Validation Filter</filter-name>
<filter-class>org.jasig.cas.client.validation.Cas10TicketValidationFilter</filter-class>
<init-param>
<param-name>casServerUrlPrefix</param-name>
<param-value>https://sso.server.com:8443/cas</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://sso.client2.com:28080</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Validation Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--
????????HttpServletRequest?????,?????????HttpServletRequest?getRemoteUser()????SSO????????,?????
-->
<filter>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--
?????????????org.jasig.cas.client.util.AssertionHolder????????????AssertionHolder.getAssertion().getPrincipal().getName()?
-->
<filter>
<filter-name>CAS Assertion Thread Local Filter</filter-name>
<filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CAS Assertion Thread Local Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
图23 正在登录client2
图24 重定向到cas server进行认证
【测试验证SSO-1】
至此,2个客户端也已经配置完毕。启动配置好的三个tomcat分别为:CAS服务端tomcat-server、2个客户端tomcat-client1、tomcat-client2。
基本的测试(跟前面的配置调试过程很像,此处不再安排截图)
访问客户端1—->跳转到casserver验证—->验证成功显示客户端1的应用 —->新开选项卡访问客户端2—->直接显示客户端2应用 —->注销casserver —->打开客户端1/客户端2 —->重新跳转到casserver验证
成功。
【测试验证SSO-2】
访问客户端2—->跳转到casserver验证—->未输入验证信息—->新开选项卡访问客户端1的应用 —->跳转到casserver验证—->验证成功显示客户端1的应用(出现Hello World)—->刷新客户端2应用—->验证成功显示客户端2的应用(出现Hello World)—->注销casserver —->打开客户端1/客户端2 —->重新跳转到casserver验证
下面截图,根据【测试验证SSO-2】流程进行测试,看看是否与该流程一致。
本案例先登录client2(图25)
http://sso.client2.com:28080/examples/servlets/servlet/HelloWorldExample,
图25 访问客户端2跳转到cas server验证
新开选项卡访问客户端1的应用,跳转到cas server验证(图26),输入用户名和密码,成功登录。
图26 client1重定向登录验证成功
重新打开一个选项卡,地址栏输入:
http://sso.server.com:8443//cas/login
回车,将直接显示服务端界面,不需登录信息直接登录成功(图27)
图27 cas server不须验证即可登录
重新打开一个选项卡,地址栏输入:
http://sso.client2.com:28080/examples/servlets/servlet/HelloWorldExample
回车,将直接显示客户端2界面,没有重新登录,浏览器显示界面:
刷新client2登录界面中(图28)。
图28 刷新client2登录界面中
图29 刷新后client2登录成功
根据上面显示的界面,按照一般逻辑,当访问服务端(Central Authentication Service)的时候,应该会被CAS拦截,进入认证服务的界面,但是结果却直接显示服务端录陆成功的界面,原因就是因为在访问客户端1的时候已经登录认证过了,CAS会在浏览器中注入COOKIE,记录认证凭证,如果的浏览器没有关闭或者退出的话,当访问服务端应用的时候,CAS检测到认证的凭证,就直接显示了服务端(Central Authentication Service)的界面。同时,刷新最初登录没有输入登录信息的client2界面,也直接显示客户端2的界面,表示client2因为同一身份认证单点登录成功。
下面,我们新打开一个选项卡(也可在当前页面的地址栏输入),在浏览器地址栏中输入(图30):https://sso.server.com:8443/cas/logout
图30 准备登出(认证注销)
回车显示见图31
图31 认证注销成功
此时如果再访问 :
http://sso.client1.com:18080/examples/servlets/servlet/HelloWorldExample
或http://sso.client2.com:28080/examples/servlets/servlet/HelloWorldExample
都将会跳转到CAS服务重新进行认证。
到此,SSO之CAS单点登录系统已经搭建完毕!
全文借鉴多篇文章,小白在此感谢各位大牛为本文提供的思路、方法、架构,谢谢你们的辛勤付出,才能使本案例成功运行。
以下是部分参考文献,因为第一次在CSDN正式发布文章,还没有形成严谨的行文格式与参考文献留底流程,今后注意。
参考文献:
https://blog.csdn.net/xqhys/article/details/65748425
https://wenku.baidu.com/view/1a797e43783e0912a2162a72.html
http://www.cnblogs.com/lr393993507/p/5231432.html
https://blog.csdn.net/huqiao1206/article/details/50768481