因为公司要使用cas,所以深入了解了一下.网上资料很多,各种原理就不累述了,说一下遇到的问题吧:
1.客户端版本选择
cas常用的有两个客户端,一个是老的耶鲁的,包名中有yale的;一个是cas client3版本,包名为jasig的。
yale版的登出好像没完全实现,不能够做到所有应用一齐登出,cas client3多一个single out filter来实现这个功能。
yale版的代理回调是通过配置servlet来处理的,cas client3通过在过滤器中处理。
相比较而言,yale的配置比较简单,网上的配置说明通常都是以yale版本为主,cas client3的配置可以看官网的wiki,
https://wiki.jasig.org/display/CASC/CAS+Client+for+Java+3.1,不过是英文的,cas client3还可以使用spring来配置,这种配置方式我自己没实验过,可以看一下文档。
2.配置中的问题
第一个问题是证书中的域,因为我们是做政府应用的,通常没有域名,只能使用ip来进行域名认证,cas本身又不支持ip的域,只能改造cas的客户端,在调用connection的openconection之前,把默认的ssl处理handle设置为javax.net.ssl,并注入一个自定义的HostnameVerifier:
System.setProperty("java.protocol.handler.pkgs", "javax.net.ssl");
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
return urlHostName.equals(session.getPeerHost());
}
};
HttpsURLConnection.setDefaultHostnameVerifier(hv);
cas client3中,以上代码加在AbstractCasProtocolUrlBasedTicketValidator的retrieveResponseFromServer方法中,我一直没找到默认的hostnameverifer实现,所以不知道为什么ip不能通过验证。
第二个是在weblogic中出现的,估计只是开发中才会出现的问题,证书太小,开发中通常都是自认证,所以会出现
FATAL Alert:BAD_CERTIFICATE - A corrupt or unuseable certificate was received.
解决方法,加入大小设置即可。
3.cas的代理认证
cas协议2.0加入了代理模式,在门户这种应用场景下相当的有用,网上的配置通常基于yale的客户端,cas client3的配置只有这篇文章有提及:
http://fallenlord.blogbus.com/logs/57175888.html,但是其中有几个需要说明的proxyCallbackUrl和proxyReceptorUrl实际上是不需要我们自己开发的,yale版中回调有一个servlet的,新版本是在过滤器中处理掉的,这个地址可以自己随意定义,proxyCallbackUrl需要使用https协议,所以需要cas server端信任cas client的证书,具体配置方法就是在客户端生成证书,加入到服务器端的信任域中间去。
4.cas的登录页
在cas保护下的应用,在未登陆的时候,都会跳转到cas服务器上进行登录,理论上sso就是这个样子的,但是有时候客户会要求我在自己的页面登录,不要跳转到cas登录页,目前我没想到好的办法,我们采用了iframe嵌入cas登录页的方式来处理(ie下iframe会话有bug,google一下)。
贴一下我们的配置文件吧:
CasTest(代理模式的发起端)
<filter>
<filter-name>CAS Single Sign Out Filter</filter-name>
<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter>
<filter>
<filter-name>CAS Authentication Filter</filter-name>
<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
<init-param>
<param-name>casServerLoginUrl</param-name>
<param-value>https://10.1.10.100:8443/cas/login</param-value>
</init-param>
<init-param>
<param-name>renew</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>gateway</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://10.1.10.100:8080</param-value>
</init-param>
</filter>
<filter>
<filter-name>CAS Validation Filter</filter-name>
<filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
<init-param>
<param-name>casServerUrlPrefix</param-name>
<param-value>https://10.1.10.100:8443/cas/</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://10.1.10.100:8080</param-value>
</init-param>
<init-param>
<param-name>useSession</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>redirectAfterValidation</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>acceptAnyProxy</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>proxyCallbackUrl</param-name>
<param-value>https://10.1.10.100:8444/CasTest/proxy</param-value>
</init-param>
<init-param>
<param-name>proxyReceptorUrl</param-name>
<param-value>/proxy</param-value>
</init-param>
</filter>
<filter>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<filter-class>
org.jasig.cas.client.util.HttpServletRequestWrapperFilter
</filter-class>
</filter>
<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 Validation Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS Single Sign Out Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS Authentication Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
CasTest2(代理模式的服务提供端)
<filter>
<filter-name>CAS Single Sign Out Filter</filter-name>
<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter>
<filter>
<filter-name>CAS Authentication Filter</filter-name>
<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
<init-param>
<param-name>casServerLoginUrl</param-name>
<param-value>https://10.1.10.100:8443/cas/login</param-value>
</init-param>
<init-param>
<param-name>renew</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>gateway</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://10.1.10.100:8080</param-value>
</init-param>
</filter>
<filter>
<filter-name>CAS Validation Filter</filter-name>
<filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
<init-param>
<param-name>casServerUrlPrefix</param-name>
<param-value>https://10.1.10.100:8443/cas</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://10.1.10.100:8080</param-value>
</init-param>
<init-param>
<param-name>useSession</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>redirectAfterValidation</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>acceptAnyProxy</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<filter-class>
org.jasig.cas.client.util.HttpServletRequestWrapperFilter
</filter-class>
</filter>
<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 Single Sign Out Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS Authentication Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS Validation Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>