【Tech】单点登录系统CAS客户端demo
服务器端配置请参考: http://www.cnblogs.com/sunshineatnoon/p/4064632.html
工具:myeclipse或者javaee-eclipse
1.启动javaee-eclipse,我启动的时候遇到了java was started but returned exit code=1的错误,搜了一下解决的方法大概有两类:
(1)eclipse目录不能有中文(我就是这个问题)
(2)修改eclipse目录下的eclipse.ini文件,在-vmargs这一行前面加上两行,一行是-vm,令一行是javaw.exe的路径,就像这样:
-vm
E:\Program Files\Java\jdk1.7.0\bin\javaw.exe
大多数情况下基本就没问题了,还有人是因为java内存分配不足引起的,网上有答案,这里就不提了。
2.eclipse中新建File->New->Other->Web->Dynamic Web Project,创建一个名叫CasClient的web工程,注意新建的时候要把Generate web.xml deployment descriptor勾选上,否则后面要手动添加web.xml文件。
3.把\cas-client-3.2.1\modules下的所有jar包拷贝到j2eeeclipseWorkSpace\CasClient\WebContent\WEB-INF\lib下。
4.把web.xml文件替换成如下的文件:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> 3 <display-name>casclient1</display-name> 4 5 <!-- 用于单点退出,该监听器用于实现单点登出功能,通知其他应用单点登出 --> 6 <listener> 7 <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class> 8 </listener> 9 10 <!-- 该过滤器用于实现单点登出功能 --> 11 <filter> 12 <filter-name>CAS Single Sign Out Filter</filter-name> 13 <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class> 14 </filter> 15 <filter-mapping> 16 <filter-name>CAS Single Sign Out Filter</filter-name> 17 <url-pattern>/*</url-pattern> 18 </filter-mapping> 19 20 <!-- 该过滤器负责用户的认证工作 --> 21 <filter> 22 <filter-name>CASFilter</filter-name> 23 <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class> 24 <init-param> 25 <param-name>casServerLoginUrl</param-name> 26 <!-- 设置登录的URL地址 --> 27 <param-value>https://localhost:8443/cas/login</param-value> 28 </init-param> 29 <init-param> 30 <param-name>serverName</param-name> 31 <!-- 设置本应用的访问地址及端口 --> 32 <param-value>http://localhost:8080</param-value> 33 </init-param> 34 </filter> 35 <filter-mapping> 36 <filter-name>CASFilter</filter-name> 37 <url-pattern>/*</url-pattern> 38 </filter-mapping> 39 40 <!-- 该过滤器负责对Ticket的校验 --> 41 <filter> 42 <filter-name>CAS Validation Filter</filter-name> 43 <filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class> 44 <init-param> 45 <param-name>casServerUrlPrefix</param-name> 46 <param-value>https://localhost:8443/cas</param-value> 47 </init-param> 48 <init-param> 49 <param-name>serverName</param-name> 50 <param-value>http://localhost:8080</param-value> 51 </init-param> 52 </filter> 53 <filter-mapping> 54 <filter-name>CAS Validation Filter</filter-name> 55 <url-pattern>/*</url-pattern> 56 </filter-mapping> 57 58 <!-- 该过滤器负责实现HttpServletRequest请求的包裹,允许开发者通过HttpServletRequest的getRemoteUser()获取SSO登录的用户 --> 59 <filter> 60 <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name> 61 <filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class> 62 </filter> 63 <filter-mapping> 64 <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name> 65 <url-pattern>/*</url-pattern> 66 </filter-mapping> 67 68 <!-- 该过滤器使得开发者可以通过org.jasig.cas.client.util.AssertionHolder来获取用户的登录名。 比如AssertionHolder.getAssertion().getPrincipal().getName()。 --> 69 <filter> 70 <filter-name>CAS Assertion Thread Local Filter</filter-name> 71 <filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class> 72 </filter> 73 <filter-mapping> 74 <filter-name>CAS Assertion Thread Local Filter</filter-name> 75 <url-pattern>/*</url-pattern> 76 </filter-mapping> 77 78 <welcome-file-list> 79 <welcome-file>index.jsp</welcome-file> 80 </welcome-file-list> 81 </web-app>
5.在j2eeeclipseWorkSpace\CasClient\WebContent\目录下新建index.jsp文件
1 <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> 2 <%@ page import="org.jasig.cas.client.authentication.AttributePrincipal" %> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 7 <title>casClient1</title> 8 </head> 9 <body> 10 <% 11 //AttributePrincipal principal = (AttributePrincipal)request.getUserPrincipal(); 12 //String userName = principal.getName(); 13 %> 14 <br />--------------------------------------------<br /> 15 <h1>登录成功,CAS客户端1。</h1><br /> 16 <!-- <h2>当前登录用户:</h2><br /> --> 17 <a href="http://localhost:8080/CasClient2/index.jsp">进入客户端2</a><br /> 18 <a href="https://localhost:8443/cas/logout">退出</a><br /> 19 </body> 20 </html>
6.在\apache-tomcat-7.0.56\webapps\下新建一个文件夹叫CasClient文件夹,然后把\j2eeeclipseWorkSpace\Cas Client\WebContent\下的两个文件夹META-INF和WEB-INF,还有index.jsp文件拷贝到刚才创建的CasClient文件夹下.
7.为了验证单点登录,用上述6步方法再创建一个CasClient2工程,也把它相应的文件拷贝到\apache-tomcat-7.0.56\webapps\CasClient下,注意CasClient2中index.jsp需要做的修改,上述15行改为:
<h1>登录成功,CAS客户端2。</h1><br />
17行改为:
<a href="http://localhost:8080/CasClient/index.jsp">进入客户端1</a><br />
这样就可以从CasClient2跳转到CasClient界面。
8.验证单点登录系统:浏览器打开页面http://localhost:8080/CasClient,这是会跳转到cas的登录页面,如下图:
注意到红色部分可以帮助我们理解CAS的工作原理,当用户访问cas client对应的资源时,被重定向到cas server并且将用户想要访问的资源用GET的方式添加在url尾部(上述红框)发送给server,方便在登录成功后直接跳转到相应的资源。
然后我们用数据库中的用户名密码登录(与mysql的对接详情参见cas server配置,链接在博文最上方),登录成功后的页面如下:
然后我们可以直接点击“进入客户端2”跳转到CasClient2,或者直接在浏览器里面输入http://localhost:8080/CasClient2跳转到CasClient2页面,如下图所示:
可以看到从CAS客户端1进入到CAS客户端2完全不需要重新登录,从CAS客户端2再次跳转回到CAS客户端1页不需要重新登录,即实现了单点登录。
在上述的过程中,我还解决了三个bug:
1.一个是提示java.security.cert.CertificateException: No name matching localhost found,解决的方法参考http://www.cnblogs.com/dycg/archive/2013/04/04/2999012.html,即重新生成一边证书(详情参见cas server配置),在回答名字和姓氏的时候,确保回答的是localhost(或者你的域名)。
2.这时用新生成的证书替换原来的证书,又报错SunCertPathBuilderException: Unable To Find Valid Certification Path To Requested Target,这个的原因和解决方法这里http://www.mkyong.com/webservices/jax-ws/suncertpathbuilderexception-unable-to-find-valid-certification-path-to-requested-target/解释的很清楚了,主要是服务端的证书没有被认证,从上述网址中总结的解决方法如下:
(1)下载InstallCert.java(国外网站上大神写的解决这个问题的java文件,我把它down下来放在自己的网盘上了,大神网页参见参考资料[4])。
(2)cd到InstallCert.java所在目录下编译运行InstallCert.java:
然后根据提示选择相应的证书(应该是输入1),就会在InstallCert.java所在的目录下生成一个jssecacerts文件。
(3)拷贝上述生成的jssecacerts文件到$JAVA_HOME\jre\lib\security目录下。
(4)重新打开网页,就没有问题了。
3.部署CasClient的时候,tomcat出现错误:java.lang.NoSuchMethodException: org.apache.catalina.deploy.WebXml addFilter
解决方法是在\apache-tomcat-7.0.57\conf\context.xml的<Context></Context>两个标签之前插入<Loader delegate="true" />;[5]
参考资料:
[1]http://bh-keven.iteye.com/blog/1317793
[2]http://www.cnblogs.com/dycg/archive/2013/04/04/2999012.html
[4]https://blogs.oracle.com/gc/entry/unable_to_find_valid_certification