一、软件版本
Tomcat6.018,
CAS-SERVER 3.3.1, CAS-CLIENT-JAVA 2.1.1
二、准备工作
1、在Tomcat配置SSL
在/$CATA_HOME$/conf/server.xml中加入下面的配置,记住端口号为8443,口令为changeit。
<Connector protocol="org.apache.coyote.http11.Http11NioProtocol"
port="8443" minSpareThreads="5" maxSpareThreads="75"
enableLookups="true" disableUploadTimeout="true"
acceptCount="100" maxThreads="200"
scheme="https" secure="true" SSLEnabled="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="server.keystore"
keystorePass="changeit" />
2、生成证书
将以下命令作为一个bat文件,双击运行它(假设CAS部署在http://1GNW92X.com.cn):
rem 生成证书,用户名输入locahost
keytool -delete -alias tomcat -keystore "%JAVA_HOME%/jre/lib/security/cacerts" -storepass changeit
keytool -delete -alias tomcat -storepass changeit
keytool -genkey -alias tomcat -keyalg RSA -keypass changeit -storepass changeit -keystore server.keystore -validity 360
rem 将证书导入的JDK的证书信任库
keytool -export -trustcacerts -alias tomcat -dname "1GNW92X.com.cn" -file server.cer -keystore server.keystore -storepass changeit
keytool -import -trustcacerts -alias tomcat -file server.cer -keystore "%JAVA_HOME%/jre/lib/security/cacerts" -storepass changeit
3、如果业务平台WebApp在CAS以外的机器上,再在业务机运行下面的指令:
java InstallCert 1GNW92X.com.cn:8443
三、配置CAS-SERVER应用
将 cas-server3.3.1.zip包里面的case-server-3.3.1.war改名cas.war放倒tomcat的webApps目录,修改/WEB-INF/deployerConfigContext.xml文件,主要替换以下几个部分:
1、<bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />
==>>
<bean id="QueryDatabaseAuthenticationHandler"
class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
<property name="dataSource" ref="casDataSource" />
<property name="sql" value="SELECT c_userpwd FROM T_USER WHERE c_userid=?" />
<!--property name="passwordEncoder" ref="myPasswordEncoder"/-->
</bean>
<bean id="casDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="oracle.jdbc.driver.OracleDriver" />
<property name="jdbcUrl" value="jdbc:oracle:thin:@172.21.6.212:1521:ORCL" />
<property name="user" value="longtop" />
<property name="password" value="longtop" />
<property name="autoCommitOnClose" value="true"/>
<property name="checkoutTimeout" value="5000"/>
<property name="initialPoolSize" value="10"/>
<property name="minPoolSize" value="10"/>
<property name="maxPoolSize" value="30"/>
<property name="maxIdleTime" value="100000"/>
<property name="acquireIncrement" value="5"/>
</bean>
2、<bean id="attributeRepository" class="org.jasig.services.persondir.support.StubPersonAttributeDao">
<property name="backingMap">
<map>
<entry key="uid" value="uid" />
<entry key="eduPersonAffiliation" value="eduPersonAffiliation" />
<entry key="groupMembership" value="groupMembership" />
</map>
</property>
</bean>
==>>
<bean id="attributeRepository" class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao">
<constructor-arg index="0" ref="casDataSource"/>
<constructor-arg index="1">
<list>
<value>username</value>
</list>
</constructor-arg>
<constructor-arg index="2" value="select c_userid,c_username,c_defaultgrp from T_USER where c_userid=?"/>
<property name="columnsToAttributes">
<map>
<entry key="c_userid" value="userId"/>
<entry key="c_username" value="fullName"/>
<entry key="c_defaultgrp" value="groupId"/>
</map>
</property>
</bean>
四、搞定客户端webApp
1、配置web.xml
<listener>
<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>
<filter>
<filter-name>CAS Single Sign Out Filter</filter-name>
<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CAS Single Sign Out Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>CAS Filter</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://1GNW92X.com.cn:8443/cas/login</param-value>
</init-param>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>
<param-value>https://1GNW92X.com.cn:8443/cas/serviceValidate</param-value>
</init-param>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>
<param-value>localhost:8080</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2、修改edu.yale.its.tp.cas.client.ServiceTicketValidator中解析报文的方法(原来是用sax),改为用jdom
private static String TAG_AUTHEN_SUCCESS = "authenticationSuccess";
private static String TAG_AUTHEN_FAILURE = "authenticationFailure";
private static String TAG_AUTHEN_USER = "user";
private static String TAG_AUTHEN_ATTRIBUTES = "attributes";
private static String TAG_AUTHEN_PGT = "proxyGrantingTicket";
private static String TAG_AUTHEN_PROXIES = "proxies";
private static String TAG_AUTHEN_ATTRIBUTE = "attribute";
private static String TAG_AUTHEN_ATTRNAME = "name";
private static String TAG_AUTHEN_ATTRVALUE = "value";
private static String TAG_AUTHEN_PROXY = "proxy";
private static String TAG_AUTHEN_ERRORCODE = "code";
@SuppressWarnings("unchecked")
private void parseResponse(String xmlContent)throws IOException, SAXException{
receipt = new CASReceipt();
receipt.setCasValidateUrl(casValidateUrl);
receipt.setProxyCallbackUrl(proxyCallbackUrl);
ByteArrayInputStream bin = new ByteArrayInputStream(xmlContent.getBytes());
SAXBuilder builder = new SAXBuilder();
builder.setValidation(false);
Document doc = null;
try {
doc = builder.build(bin);
} catch (JDOMException e) {
throw new SAXException(e);
}
Element root = doc.getRootElement().getChild(TAG_AUTHEN_SUCCESS);
if (root != null){
List<Element> lstNode = root.getChildren();
List<Element> userAttrs;
List<Element> proxyList;
for (Element node : lstNode){
if (node.getName().equals(TAG_AUTHEN_USER)){
receipt.setUserName(node.getTextTrim());
}else if (node.getName().equals(TAG_AUTHEN_ATTRIBUTES)){
userAttrs = node.getChildren(TAG_AUTHEN_ATTRIBUTE);
for (Element attr : userAttrs){
receipt.putUserAttribute(
attr.getChildTextTrim(TAG_AUTHEN_ATTRNAME),
attr.getChildTextTrim(TAG_AUTHEN_ATTRVALUE) );
}
}else if (node.getName().equals(TAG_AUTHEN_PGT)){
receipt.setPgtIou(node.getTextTrim());
}else if (node.getName().equals(TAG_AUTHEN_PROXIES)){
proxyList = node.getChildren(TAG_AUTHEN_PROXY);
for (Element proxy : proxyList){
this.proxyList.add( proxy.getTextTrim() );
}
}
}
}else{
root = doc.getRootElement().getChild(TAG_AUTHEN_FAILURE);
errorCode = root.getAttributeValue(TAG_AUTHEN_ERRORCODE);
errorMessage = root.getTextTrim();
}
}
修改validate()
private CASReceipt receipt;
protected List proxyList;
public void validate() throws IOException, SAXException,
ParserConfigurationException {
//前面的部分不修改
String response = SecureURL.retrieve(sb.toString());
response = response.replaceAll("<cas:", "<").replaceAll("</cas:", "</");
this.parseResponse(response);
if (!receipt.validate()) {
throw new ParserConfigurationException(
"Validation of [" + this
+ "] did not result in an internally consistent CASReceipt.");
}
}
public CASReceipt getReceipt(){
return this.receipt;
}
3、修改CASFilter
private ILoginClientService loginClient; //自定义的接口,用于实现客户端的Session
private CASReceipt getAuthenticatedUser(HttpServletRequest request)
throws ServletException, CASAuthenticationException {
//前面的部分不修改
//return CASReceipt.getReceipt(ServiceTicketValidator);
try {
ticketValidator.validate();
return ticketValidator.getReceipt();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain)throws ServletException, IOException {
//前面的部分不修改
if (loginClient != null){
System.out.println("application do login and set session....");
loginClient.login(request, response, receipt.getUserName());
}
chain.doFilter(request, response);
}
public void init(FilterConfig config) throws ServletException {
//前面的部分不修改
if (loginClient != null){
System.out.println("application do login and set session....");
loginClient.login(request, response, receipt.getUserName());
}
chain.doFilter(request, response);
}
4、新增类
public interface ILoginClientService{
public static String REFER_ID = "com.longtop.dev6sso.LoginService";
public void login(HttpServletRequest request, HttpServletResponse response,
String loginName);
public void logout(HttpServletRequest request, HttpServletResponse response,
String loginName);
}
5、别忘了在客户端Spring配置
<bean id="com.longtop.dev6sso.LoginService"
class="com.longtop.demo.sso.DemoLoginService">
</bean>
==================================================
End.