1. 开发说明
1.1. 开发目的
为了满足portal门户与各个子系统统一登录的需求,从而使用CAS进行SSO单点登录的配置开发。此开发文档是在开发过程中编写整合,提供项目组开发人员做为参考。
1.2. 预期读者
(1)系统设计人员
(2)平台开发人员
(3)系统维护人员
1.3. 开发资源
开发中所使用的资源版本如下说明,不同的版本所使用的配置方法及开发步骤不同,请注意相应的版本号。
环境要求
JDK 1.4.2
|
Websphere6.0.2.15
|
开发使用Liferay portal 4.3.0门户平台框架,测试环境使用liferay绑定的tomacat5.X+JDK1.4,可以从http://www.liferay.com/官网上下载其绑定的相关版本进行整合开发。
单点登陆服务端使用liferay整合后的liferay-portal-cas-web-4.3.0.war进行配置,其集成使用的CAS版本为cas-server-3.0.5.jar,客户端使用CAS Client2.11;相关资料文档可查看http://www.ja-sig.org/products/cas/相关文档。
2. CAS-SERVER
2.1. 项目说明
CAS是Yale大学的ITS开发的一套JAVA实现的开源的SSO的服务。该服务是以一个java web app(eg:cas.war)来进行服务的,使用时需要将cas.war发布到一个servlet2.3兼容的服务器上,并且服务器需要支持SSL,在需要使用该服务的其他服务器(客户端),配置相应的以fitle实现SSO。
在liferay portal项目中,使用自已集成的liferay-portal-cas-web-4.3.0.war,也可在cas的官方站点中下载相应原码cas-server-3.0.5.zip进行修改!
2.2. 目录结构
下载cas-server-3.0.5.zip后进行解压,将原码core"src导入至eclipse中,目录结构如下:
在cas-server项目中需增加身份验证,使用portal项目用户表[lportal.user_]进行登录,为了程序开发的方便,我们将使用portal集成liferay-portal-cas-web-4.3.0.war的项目新建web项目进行server端的修改测试工作。
3. CAS WEB应用
3.1. 项目说明
在lifreay项目中下载liferay-portal-cas-web-4.3.0.war,里面集成了SSO单点登录的开发方法。
将项目导入eclipse进行二次开发。
使用liferay portal进行CAS Server配置,其配置方法在liferay官方文档中有详细的说明:
http://content.liferay.com/4.3/doc/installation/liferay_4_installation_guide/multipage/ch05s04.html
1、下载Liferay-portal-cas-4.3.x.war;下载地址 www.liferay/web/guest/downloads
2、并将下载的war更名为cas.war,发布至tomcat下,进行相关设置。具体的发布方法需进行数字签名和tomcat环境配置工作。
3、系统发布测试。
3.2. 目录结构
将war包解压导入至eclpise进行开发整合,我们使用web项目进行修改发布。
导入后的目录如下:
3.3. 页面改造
Ø CAS汉化改造:
在src下使用eclipse的properties插件翻译messages.properties,如:
screen.welcome.welcome=欢迎您进入PORTAL平台
Ø CAS页面改造:
对基本的登录登出页面及布局进行改造,以适合信息平台的需要,具体的改造页面主要包括:
"cas"WEB-INF"view"jsp"default"ui"casLoginView.jsp —登录页面
"cas"WEB-INF"view"jsp"default"ui"casLogoutView.jsp —登出页面
"cas"WEB-INF"view"jsp"default"ui"casLogoutView.jsp —登出页面
"cas"WEB-INF"view"jsp"default"ui"casGenericSuccess.jsp —录成功页面
"cas"WEB-INF"view"jsp"default"ui"includes"top.jsp —包含的头文件
"cas"WEB-INF"view"jsp"default"ui"includes"bottom.jsp —包含的头脚文件
......
3.4. 授权改造
CAS跟普通的Web系统融合认证和授权,需增加java授权文件,此文件继承AbstractUsernamePasswordAuthenticationHandler ,并进行验证。
1、在src下增加DBHandlers.java
DBHandlers
package com.yitong.cas.auth.provider;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import org.apache.log4j.Logger;
import org.jasig.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler;
import org.jasig.cas.authentication.principal.UsernamePasswordCredentials;
/**
* @author soju
* @version 1.0
*
*/
public final class DBHandlers extends
AbstractUsernamePasswordAuthenticationHandler {
private Logger log = Logger.getLogger(DBHandlers.class);
/**
* 相关的数据库配置DS对应的jndi
*/
private String _jndi = "lportal";
public boolean authenticateUsernamePasswordInternal(
final UsernamePasswordCredentials credentials) {
String username = credentials.getUsername();
String password = credentials.getPassword();
log.info("username:" + username);
log.info("password:" + password);
try {
password = Security.encryptMD5(password);
log.debug("md5password" + password);
} catch (Exception e) {
log.warn("MD5加密出错", e);
throw new Exception("MD5加密出错");
return false;
}
try {
if (checkuser(username, password) == 1) {
getLog().info("认证成功!");
return true;
}
} catch (Exception e) {
log.warn("failed authentication", e);
}
return false;
}
private int checkuser(String user, String pwd) throws Exception {
int ok= 0;
Context initCtx = new InitialContext();
DataSource ds = (DataSource) initCtx.lookup(_jndi);
Connection conn = ds.getConnection();
String sql = "select * from user_ where screenname='"+ user + "' and password_='" + pwd + "' ";
log.info("sql= " + sql);
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(sql);
log.info("登录成功!");
if (rs.next()) {
Ok=1;
} else {
log.info("帐号不存在或密码错误!");
}
conn.close();
return rei;
}
protected void afterPropertiesSetInternal() throws Exception {
super.afterPropertiesSetInternal();
}
}
|
2、修改WEB-INF"deployerConfigContext.xml下文件:
<bean class="org.jasig.cas.authentication.handler.support.
SimpleTestUsernamePasswordAuthenticationHandler" />
<bean class="com.yitong.cas.auth.provider.DBHandlers" />
|
将此项目在tomcat中进行测试,当然首先配置数字签名及tomcat测试环境
4. 数字签名
4.1. 生成密钥
设置你的JDK_HOME;将JDK的BIN加入系统变量中或是直接在jdk bin下使用如下命令
在CMD下输入如下命令:
keytool -genkey -alias cas -keyalg RSA -keysize 1024 -validity 3650 -keystore ${USER_ROOT }/keystore.jks
输入keystore密码: changeit
您的名字与姓氏是什么?
[Unknown]: xxx.xxx.xxx..xxx
您的组织单位名称是什么?
[Unknown]:
您的组织名称是什么?
[Unknown]:
您所在的城市或区域名称是什么?
[Unknown]:
您所在的州或省份名称是什么?
[Unknown]:
该单位的两字母国家代码是什么
[Unknown]:
CN=192.168.13.100, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown 正确
吗?
[否]: y
输入<cas>的主密码
(如果和 keystore 密码相同,按回车):
|
说明:
1、 cas 为密钥的别名;
2、 您的名字与姓氏是什么提示时请输入你所在server的域名或IP地址,即你发布的websphere 所在的域名或IP地址,如192.168.1.100
3、 ${USER_ROOT }/keystore.jks为您所生成的文件存放目录。
4、 可使用命令查看证书内容
C:">keytool -list -keystore ${USER_ROOT }/keystore.jks
输入keystore密码: changeit
Keystore 类型: jks
Keystore 提供者: SUN
您的 keystore 包含 2 输入
websphere, 2007-12-19, keyEntry,
认证指纹 (MD5): 42:F8:BD:B2:C1:5B:9B:17:33:F2:05:AF:41:31:8B:FC
casserver, 2007-12-19, keyEntry,
认证指纹 (MD5): 66:47:03:0C:FC:D2:3E:18:80:98:3F:5B:C5:84:5E:9E
|
4.2. 导出证书
keytool -export -alias cas -keystore ${USER_ROOT }/keystore.jks -file ${USER_ROOT }/cas.cer
输入keystore密码: changeit
保存在文件中的认证 <${USER_ROOT }/cas.cer>
|
说明:
将密钥cas导成cas.cer证书文件;${USER_ROOT }为导出的目录
4.3. 导入证书
keytool -import -alias casserver -keystore %JAVA_HOME%/jre/lib/security/cacerts -file ${USER_ROOT }/cas.cer -trustcacerts
输入keystore密码: changeit
Owner: CN=xxx.xxx.xxx.xxx, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
发照者: CN=xxx.xxx.xxx.xxx, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unkn
own
序号: 47690c06
有效期间: Wed Dec 19 20:18:14 CST 2007 至: Sat Dec 16 20:18:14 CST 2017
认证指纹:
MD5: 66:47:03:0C:FC:D2:3E:18:80:98:3F:5B:C5:84:5E:9E
SHA1: F8:D5:B7:5D:20:F8:61:32:D0:1D:99:61:89:40:BF:73:6C:84:BA:58
信任这个认证? [否]: y
认证已添加至keystore中
|
说明:
1、 导入${USER_ROOT }/cas.cer证书文件;
2、 %JAVA_HOME%/jre/lib/security/cacerts为您服务器所使用的JVAV环境里,将证书导入至JVM中。
5. Tomcat配置
1、修改配置:tomcat"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"
keystoreFile="${USER_ROOT }/ keystore.jks"
keystorePass="changeit"
sslProtocol="TLS">
</Connector>
|
2、根据生成的 keystore.jks,导入至web server所使用的JVM,设置完成后重新启动tomcat,进行页面测试。
3、测试路径:https://server IP:8443/cas
6. CAS-CLIENT
6.1. 配置要求
CAS 的客户端可以有很多种,因为验证的结果是以XML的格式返回的,故可以根据
需要实现一个自己的客户端。
http://www.yale.edu/tp/cas/cas-client-2.0.11.zip
http://www.ja-sig.org/products/cas/client/index.html
开发所需配置包,注意版本问题,会因版本开发的client不同
包名
|
说明
|
spring-mock.jar
|
jwebunit-1.3.zip
|
httpunit-1.6.2.zip
|
junit-4.4.zip
|
6.2. 目录结构
将cas-client-2.0.11.zip解压后导入eclipse工程,目录结构如下:
6.3. 代码配置
1、修改代码SecureURL.java,因数字签名只能使用只能是域名,而不能是IP之类的代替,故修改如下代码
edu.yale.its.tp.cas.util
//URLConnection uc = u.openConnection();
/**
* @sojust
* 由于hostname 只能是域名,而不能是IP之类的 屏蔽掉对hostname的校验
* http://forum.java.sun.com/thread.jspa?threadID=521779
* begin
*/
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
System.out.println("Warning: URL Host: "+urlHostName+" vs."+session.getPeerHost());
return true;
}
};
HttpsURLConnection.setDefaultHostnameVerifier(hv);
HttpsURLConnection uc= (javax.net.ssl.HttpsURLConnection)u.openConnection();
//end
|
2、修改Build.xml,将代码打包发布
<target name="deploy">
<mkdir dir="build"/>
<mkdir dir="build/META-INF"/>
<javac srcdir="src"
destdir="build"
deprecation="false"
classpathref="project.classpath"
/>
<copy todir="build/META-INF">
<fileset dir="conf">
<include name="*"/>
</fileset>
</copy>
<jar jarfile="lib/casclient.jar" basedir="build"/>
</target>
<path id="project.classpath">
<path refid="lib.classpath" />
</path>
<path id="lib.classpath">
<fileset dir="lib" includes="*.jar" />
</path>
|
7. PORTAL平台接入
7.1. 资源介绍
Liferay portal作为sso一个的客户端,使用Liferay-portal-cas-4.3.x.war进行配置比较简介,特别是4.0版本后的配置,其官网上有详细的说明介绍:
http://content.liferay.com/4.3/doc/installation/liferay_4_installation_guide/multipage/ch05s04.html
7.2. 代码配置
修改portal-ext.properties ,如果系统中没有则创建一个portal-ext.properties ;打开portal-ext.properties并增加如下代码:
cas.auth.enabled=true
cas.login.url=https://server IP:port/cas/login
cas.logout.url=https://server IP:port/cas/logout
cas.service.url=http:// client IP:port/portal/c/portal/login
cas.validate.url=https:// server IP:port/cas/proxyValidate
|
配置完成后,测试client的portal,登录http:// client IP:port/portal/c/portal/login
(我的项目中增加/portal项目名称),系统会自动跳转至SSO登录界面,登录后会跳转回client的portal。登录成功!
8. 其它系统接入
8.1. 子系统配置
其它客户端子系统接入时需将提供的casclient.jar包烤入到应用"WEB-INF"lib 下,并进行相关配置。
8.2. wab.xml配置
在wab中加入CASFilter,设置跳转过滤!
<!-- CAS Filters -->
<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://server IP:port/cas/login</param-value>
</init-param>
<!--这里的server是服务端的IP-->
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>
<param-value>https://server IP:port/cas/proxyValidate</param-value>
</init-param>
<!--这里的serName是服务端的主机名-->
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>
<param-value>client IP:port</param-value>
<!--client:port就是需要CAS需要拦截的地址和端口,一般就是这个启动的IP和port-->
</init-param>
<init-param>
<param-name>needSession</param-name>
<param-value>1</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CASFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
|
8.3. 接口开发
在客户端的action中通过以下语句得到用户账号:
String userid = (String) ses.getAttribute(CASFilter.CAS_FILTER_USER);
从而编写用户认证,认证后请直接跳转到展示页面
具体应用举例:
使用struts进行用户登录跳转的使用如下方法进行开发:
Ø Struts action
public ActionForward excuse(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
HttpSession ses = request.getSession();
String userid = (String) ses.getAttribute(CASFilter.CAS_FILTER_USER);
System.out.println(userid);
……
return mapping.findForward("index");//您的展示面地址
}
|
使用servlet进行页面登录跳转的:
Ø Servlet action
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession ses = request.getSession();
String user = (String) ses.getAttribute(CASFilter.CAS_FILTER_USER); System.out.println(userid);
……
String loginUrl =””;//您的展示面地址
response.sendRedirect(loginUrl);
}
|
9. websphere配置
Websphere6支持SSL双向认证,具体的安装认证步骤如下:
1、启动websphere;并查看端口。
Ws默认的端口是9060,web端口是9080,SSL端口是9443
2、配置SSL
在安全性—>SSl 进入SSL 配置指令表,修改DefaultSSLSettings中的密钥文件名及密码。
修改如下图所示:
密钥文件名为${USER_ROOT }/ keystore.jks.jks
信任文件名为${USER_ ROOT }/keystore.jks.jks
3、修改完成后保存测试。
https://websphere ip:9443/ PlantsByWebSphere
(说明:一定要使用webspehre ip地址,与签证所使用的名字一至)
注意:使用webspehre 时将jks导入至ibm JDK的JVM,否则系统找不到相关密钥。