Liferay中使用CAS实现单点登陆(SSO)

单点登陆(SSO)的实现方式有很多种,这里所说的是用CAS实现,这也是Liferay中所采纳的方式。至于什么是CAS,单点登陆实现的原理等,这里不做解释,直接一步一步明说实现方式,好了,多一个字的费话也不说了。

第一步,创建证书

keytool -genkey -alias tomcat -keystore c:\mykeystore  -dname "CN=xyb, OU=localhost, O=localhost, L=SH, ST=SH, C=CN" -keypass 123456 -storepass 123456

PS:

 -genkey         创建一个证书
-alias          证书的别名
-keystore       指定生成此证书的路径(可不写,默认存在系统的Home目录下.keystore文件中
-storepass      指定密钥库的密码
-keypass        指定别名条目的密码
-dname          指定证书拥有者信息(可不写,但,系统会提示你依次输入这些信息,特别要注意“CN”的值是你想做为CAS服务器的这台机器的域名或机器名,但就是不能是IP)
-keyalg         指定密钥的算法(可不写)   
-validity       指定创建的证书有效期多少天(可不写,默认为90天)

第二步,导出证书

keytool -export -alias tomcat -keystore c:\mykeystore -file c:\mycerts.cer -storepass 123456

PS:

-export         将别名指定的证书导出到文件
-keystore       指定生成此证书的路径(上一步中写的什么这就写什么,如果没写,这也不写)
 -file           指定导出到文件的文件名

第三步,把导出的证书导入到客户端服务器

keytool -import -trustcacerts -alias tomcat -keystore "%JAVA_HOME%/JRE/LIB/SECURITY/CACERTS" -storepass 123456 -file c:\mycerts.cer

PS:

-import         将已签名数字证书导入密钥库
-file           指定要导入到密钥库的文件名(也就是上一步导出的那个文件)
有一个提示:是否信任这个证书,输入 Y,回车。

第四步,下载cas集成包。将下载后的文件改名为cas-web,放置在liferay的webapps目录下,在conf/server.xml中找到下面这段,去掉原有的注释并修改为:

<Connector port="8443" maxHttpHeaderSize="8192" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" disableUploadTimeout="true" acceptCount="100" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" URIEncoding="UTF-8"  keystorePass="123456" keyAlias="tomcat"/>

第五步,在Liferay的webapps\ROOT\WEB-INF\classes\portal-ext.properties下添加如下内容:

cas.auth.enabled=true
cas.login.url=https://xyb:8443/cas-web/login
cas.logout.url=https://xyb:8443/cas-web/logout
cas.server.name=客户端IP:8080
cas.service.url=
#cas.service.url=http://localhost:8080/c/portal/login
cas.validate.url=https://xyb:8443/cas-web/proxyValidate

如果没在Liferay下,只是普通的Web程序可用Filter来实现,打开Web-INF\Web.XML文件,增加如下代码

<filter>
        
<filter-name>CASFilter</filter-name>
        
<filter-class>edu.yale.its.tp.cas.client.filter.CASFilter</filter-class>
        
<init-param>
            
<param-name>edu.yale.its.tp.cas.client.filter.loginUrl</param-name>
            
<param-value>https://xyb:8443/cas-web/login</param-value>
        
</init-param><!--这里的xyb是CAS服务端的IP或机器名-->
        
<init-param>
            
<param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>
            
<param-value>https://xyb:8443/cas-web/proxyValidate</param-value>
        
</init-param>
        
<init-param>
          
<param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>
          
<param-value>localhost:8080</param-value><!--client:port就是需要CAS需要拦截的地址和端口,一般就是这个TOMCAT所启动的IP和port-->
        
</init-param>
    
</filter>
    
    
<filter-mapping>
        
<filter-name>CASFilter</filter-name>
        
<url-pattern>/*</url-pattern><!--这里就是你要拦截的URL请求-->
    
</filter-mapping>

 

最后一步,在客户端获取CAS认证通过的用户名,并修改身份验证程序为只通过用户名来验证。如是在Liferay下就不用做这一步了,Liferay中本身的验证是ScreenName字段

1、在JSP或Servlet中的用法:

<%@ page import="edu.yale.its.tp.cas.client.filter.CASFilter" %>
<%@ page import="javax.servlet.http.HttpServletRequest" %>
<%@ page import="javax.servlet.http.HttpSession" %>
<%
HttpSession ses 
= request.getSession();

String screenName 
=
(String)ses.getAttribute(CASFilter.CAS_FILTER_USER);
System.out.println(
"screenName==:"+screenName);
%> 

2、在Java中通过 Session 获取登录用户名

// 以下两者都可以
session.getAttribute(CASFilter.CAS_FILTER_USER);
session.getAttribute(
"edu.yale.its.tp.cas.client.filter.user");

3、在 JSTL 中获取用户名的方法

<c:out value="${sessionScope[CAS:'edu.yale.its.tp.cas.client.filter.user']}"/>


问题汇总:

 严重: edu.yale.its.tp.cas.client.CASAuthenticationException: Unable to validate ProxyTicketValidator [[edu.yale.its.tp.cas.client.ProxyTicketValidator prox
yList=[null] [edu.yale.its.tp.cas.client.ServiceTicketValidator casValidateUrl=[https://192.168.1.111:8443/cas/proxyValidate] ticket=[ST-0-9h7Mx5HK3pfsdxRv
MD3y] service=[http%3A%2F%2F192.168.1.222%3A8080%2Fservlets-examples%2Fservlet%2FHelloWorldExample] renew=false]]]

这个CAS异常是从CAS Client里面抛出,是当我们不使用证书的CN去访问域名的时候(比如上文是用IP访问而且证书的CN是该IP对应的域名而非该IP),CASClient无法信任,也就是我上面特意提到的那个CN的问题。要特别注意。

还有一种情况就是客户端证书没有导入,同样也报这个错误,最终可以归为一句话,肯定是证书验证没有通过所致.

 

INFO [org.jasig.cas.authentication.AuthenticationManager
Impl] - <AuthenticationHandler: cn.com.tiansky.cas.authenticationHandlers.UPAuthenticationHandler successfully authenticated the user which provided the followi
ng credentials: [username: test]>

就种错误,可能是客户端的那个配置文件里写的不太对。也就是上面说的第五步,要多注意一下。

 

java.io.IOException: Cannot recover key
        at org.apache.tomcat.util.net.jsse.JSSE14SocketFactory.init(JSSE14Socket
Factory.java:125)
        at org.apache.tomcat.util.net.jsse.JSSESocketFactory.createSocket(JSSESo
cketFactory.java:88)
        at org.apache.tomcat.util.net.PoolTcpEndpoint.initEndpoint(PoolTcpEndpoi
nt.java:292)
        at org.apache.coyote.http11.Http11BaseProtocol.init(Http11BaseProtocol.j
ava:138)
        at org.apache.catalina.connector.Connector.initialize(Connector.java:101

这种错误,可能是你生成的证书有问题,如果keypass和storepass的密码不一致也会把这个错(不知为什么非要设成一样的)



眼镜蛇

posted on 2009-02-22 12:53 眼镜蛇 阅读(3686) 评论(4)  编辑  收藏 所属分类: JavaLiferaySSO

评论

# re: Liferay中使用CAS实现单点登陆(SSO)[未登录] 2010-01-09 11:47 ben

我遇到过此问题,是我的jdk导入错误。
因为我在eclipse下配置好证书,换到MyEclipse下时,默认使用的是MyEclipse的jdk,所以就出现了上述错误。
希望能给你点帮助!  回复  更多评论   

# re: Liferay中使用CAS实现单点登陆(SSO) 2010-01-26 11:07 wacel

自己写的portlet有自己的用户系统,也要用CAS实现单点登陆,这时的web.xml应该怎么写?filter的url-pattern不管怎么写也不执行这个filter啊!  回复  更多评论   

# re: Liferay中使用CAS实现单点登陆(SSO) 2010-01-28 22:22 眼镜蛇

请看我的第五步,<url-pattern>/*</url-pattern><!--这里就是你要拦截的URL请求-->
@wacel
  回复  更多评论   

# re: Liferay中使用CAS实现单点登陆(SSO) 2013-10-17 13:50 张明

好  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 
<2013年10月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

导航

统计

常用链接

留言簿(6)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜