搞了老半天,单点登录终于弄好了,此文是初步接触单点登录的入门指南,分享一下:
准备环境:
- windows7 64位
- JDK 1.6.0_10
- Tomcat 6.0.20(准备三份tomcat,分别名为tomcat-6.0.20-app1,tomcat-6.0.20-app2,tomcat-6.0.20-cas-server,修改startup和shutdown的端口)
- CAS-server-4.0.0、CAS-client-3.3.3
127.0.0.1 server.cas.com 127.0.0.1 app1.cas.com 127.0.0.1 app2.cas.com
-
server.cas.com =>> 对应部署cas server的tomcat(tomcat-6.0.20-cas-server),这个虚拟域名还用于证书生成
-
app1.cas.com =>> 对应部署app1 的tomcat(tomcat-6.0.20-app1)
-
app2.cas.com =>> 对应部署app2 的tomcat(tomcat-6.0.20-app2)
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
keystoreFile="D:/ssodemo.keystore" keystorePass="michaelpwd"
clientAuth="false" sslProtocol="TLS" URIEncoding="UTF-8"/>
参数说明:
keystoreFile 就是4.1中创建证书的路径
keystorePass 就是4.1中创建证书的密码
3.2、配置cas-service
找到cas-server-webapp-4.0.0.war,命名为casTest.war,将该war包放到tomcat-6.0.20-cas-server/webapp下
启动该tomcat,在浏览器输入 http://server.cas.com:8443/casTest/login,若显示如下界面,说明service端配置成功。
CAS-Client 下载地址:http://downloads.jasig.org/cas-clients/
以cas-client-3.2.1-release.zip 为例,解压提取cas-client-3.2.1/modules/cas-client-core-3.2.1.jar
随便找一个简单的web项目,命名为client, 将 cas-client-core-3.2.1.jar放到该web项目下,分别将项目放到
tomcat-6.0.20-app1和tomcat-6.0.20-app2中。
4.1、配置tomcat-6.0.20-app1
<!-- ======================== 单点登录开始 ======================== -->
<!-- 用于单点退出,该过滤器用于实现单点登出功能,可选配置-->
<!-- 注意:CAS登录Filter必须在所有web应用程序Filter之前 -->
<listener>
<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>
<!-- 该过滤器用于实现单点登出功能,可选配置。 -->
<filter>
<filter-name>casSignOutFilter</filter-name>
<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>casSignOutFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>casFilter</filter-name>
<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
<init-param>
<param-name>casServerLoginUrl</param-name>
<!-- 单点登录服务器 -->
<param-value>https://service.cas.com:8443/casTest/login</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<!-- client-1 -->
<param-value>http://app1.cas.com:8060</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>casFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 该过滤器负责对Ticket的校验工作,必须启用它 -->
<filter>
<filter-name>casValidationFilter</filter-name>
<filter-class>
org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
<init-param>
<param-name>casServerUrlPrefix</param-name>
<param-value>https://service.cas.com:8443/casTest</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://app1.cas.com:8060</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>casValidationFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--
该过滤器负责实现HttpServletRequest请求的包裹,
比如允许开发者通过HttpServletRequest的getRemoteUser()方法获得SSO登录用户的登录名,可选配置。
-->
<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>
<!--
该过滤器使得开发者可以通过org.jasig.cas.client.util.AssertionHolder来获取用户的登录名。
比如AssertionHolder.getAssertion().getPrincipal().getName()。
-->
<filter>
<filter-name>casAssertionThread LocalFilter</filter-name>
<filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>casAssertionThread LocalFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- ======================== 单点登录结束 ======================== -->
<!-- ======================== 单点登录开始 ======================== -->
<!-- 用于单点退出,该过滤器用于实现单点登出功能,可选配置-->
<!-- 注意:CAS登录Filter必须在所有web应用程序Filter之前 -->
<listener>
<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>
<!-- 该过滤器用于实现单点登出功能,可选配置。 -->
<filter>
<filter-name>casSignOutFilter</filter-name>
<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>casSignOutFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>casFilter</filter-name>
<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
<init-param>
<param-name>casServerLoginUrl</param-name>
<!-- 单点登录服务器 -->
<param-value>https://service.cas.com:8443/casTest/login</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<!-- client-2 -->
<param-value>http://app2.cas.com:8070</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>casFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 该过滤器负责对Ticket的校验工作,必须启用它 -->
<filter>
<filter-name>casValidationFilter</filter-name>
<filter-class>
org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
<init-param>
<param-name>casServerUrlPrefix</param-name>
<param-value>https://service.cas.com:8443/casTest</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://app2.cas.com:8070</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>casValidationFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--
该过滤器负责实现HttpServletRequest请求的包裹,
比如允许开发者通过HttpServletRequest的getRemoteUser()方法获得SSO登录用户的登录名,可选配置。
-->
<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>
<!--
该过滤器使得开发者可以通过org.jasig.cas.client.util.AssertionHolder来获取用户的登录名。
比如AssertionHolder.getAssertion().getPrincipal().getName()。
-->
<filter>
<filter-name>casAssertionThread LocalFilter</filter-name>
<filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>casAssertionThread LocalFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- ======================== 单点登录结束 ======================== -->
Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No name matching localhost found
<c:if test="${fn:length(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes) > 0}">
<cas:attributes>
<c:forEach var="attr" items="${assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes}">
<cas:${fn:escapeXml(attr.key)}>${fn:escapeXml(attr.value)}</cas:${fn:escapeXml(attr.key)}>
</c:forEach>
</cas:attributes>
</c:if>
AttributePrincipal principal = (AttributePrincipal)request.getUserPrincipal();
String username = principal.getName();