Tomcat下ssl协议配置
一、生成 server key :
以命令行方式切换到目录tomcat安装目录%TOMCAT_HOME%下,在command命令行输入如下命令:
keytool -genkey -alias tomcat -keyalg RSA -keypass changeit -storepass changeit -keystore server.keystore -validity 3600
用户名输入域名,如localhost(开发或测试用)或hostname.domainname(用户拥有的域名),其它全部以 enter 跳过,最后确认,此时会 在%TOMCAT_HOME%下生成server.keystore 文件。
注:参数 -validity 指证书的有效期(天),缺省有效期很短,只有90天。
二、将证书导入的JDK的证书信任库中:
这步对于Tomcat的SSL配置不是必须,但对于CAS SSO是必须的,否则会出现如下错误:edu.yale.its.tp.cas.client.CASAuthenticationException: Unable to validate ProxyTicketValidator。。。
导入过程分2步,第一步是导出证书,第二步是导入到证书信任库,命令如下:
keytool -export -trustcacerts -alias tomcat -file server.cer -keystore server.keystore -storepass changeit
keytool -import -trustcacerts -alias tomcat -file server.cer -keystore C:/Program Files/Java/jdk1.6.0_21/jre/lib/security/cacerts -storepass changeit
注意是把证书导入到tomcat运行的那个jre环境下
三、修改server.xml
tomcat-5.5.35配置:
<Connector protocol="org.apache.coyote.http11.Http11Protocol"
port="8443" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true"
acceptCount="100" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="/server.keystore" keystorePass="changeit"/>
四、测试SSL
cas-server-3.1.1\modules中的cas-server-webapp-3.1.1更名为为cas.war,拷贝到Tomcat/webapps中。
启动tomcat访问 https://localhost:8443/cas/,出现CAS的登录页面则说明配置成功
Tomcat下CAS与系统的集成
一、CAS的JDBC认证
用户的认证信息通常保存在数据库中,因此本文就选用这种情况来介绍。将前面下载的 cas-server-3.1.1-release.zip 包解开后,在 modules 目录下可以找到包 cas-server-support-jdbc-3.1.1.jar,其提供了通过 JDBC 连接数据库进行验证的缺省实现,基于该包的支持,我们只需要做一些配置工作即可实现 JDBC 认证。
这里以mysql为例子:
1、打开webapps/cas/WEB-INF/deployerConfigContext.xml,添加一个新的 bean 标签:
<bean id="casDataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://127.0.0.1:3306/ccpms</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>tiger</value>
</property>
</bean>
<bean id="MD5PasswordEncoder" class="org.jasig.cas.authentication.handler.Crypt"><!--自定义密码加密器-->
2、找到<bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />后注释掉,然后下面添加
<bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
<property name="dataSource" ref="casDataSource" />
<property name="sql" value="select staff_pwd from gf_staffs where staff_id=?" /><!--sql:根据用户名查询用户的密码-->
<property name="passwordEncoder" ref="MD5PasswordEncoder"/><!--配置密码加密器-->
</bean>
3、自定义密码加密器
CAS提供默认的MD5密码加密器DefaultPasswordEncoder,但是我用这个加密器不好使,可能加密方式不一样吧,所以最保险的做法就是自定义一个加密器。
见步骤1、2的配置,其中Crypt为我自定义的密码加密器,只要在其中实现PasswordEncoder接口和encode方法即可:
.....implements PasswordEncoder
public String encode(String s)
{
String ecd = getMD5ofStr(s);
return ecd;
}
JDBC认证依赖的包:
- 将 cas-server-support-jdbc-3.1.1.jar 拷贝到 %CATALINA_HOME%/webapps/cas/ WEB-INF/lib 目录。
- 数据库驱动,由于这里使用mysql,mysql驱动拷贝到 %CATALINA_HOME%/webapps/cas/WEB-INF/lib 目录。对于其他数据库,同样将相应数据库驱动程序拷贝到该目录。
- DataStore 依赖于 commons-collections-3.2.jar, commons-dbcp-1.2.1.jar, commons-pool-1.3.jar,需要到 apache 网站的 Commons 项目下载以上 3 个包放进 %CATALINA_HOME%/webapps/cas/WEB-INF/lib 目录。
1、新建两个casclient项目casTest1和casTest2,分别部署到B、C机器上(假如casserver部署在A机器上),每个项目新建一个简单的servlet,代码如下:
public class WelcomePage extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>Welcome to casTest2 sample System!</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Welcome to casTest1 sample System!</h1>");
CASFilterRequestWrapper reqWrapper=new CASFilterRequestWrapper(request);
out.println("<p>The logon user:" + reqWrapper.getRemoteUser() + "</p>");
HttpSession session=request.getSession();
out.println("<p>The logon user:" +
session.getAttribute(CASFilter.CAS_FILTER_USER) + "</p>");
out.println("<p>The logon user:" +
session.getAttribute("edu.yale.its.tp.cas.client.filter.user") + "</p>");
out.println("</body>");
out.println("</html>");
}
}
2、在下载的cas-client-java-2.1.1\dist下找到casclient.jar包后复制到casTest1和casTest2的WEB-INF/lib下,下面以B举例,修改web.xml:
<web-app>
.......
<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://domainA:8443/cas/login</param-value>
<!--指定 CAS 提供登录页面的 URL-->
</init-param>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>
<param-value>https://domainA:8443/cas/serviceValidate</param-value>
<!--指定 CAS 提供 service ticket 或 proxy ticket 验证服务的 URL-->
</init-param>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>
<param-value>domainB:8080</param-value>
<!--指定客户端的域名和端口,是指客户端应用所在机器而不是 CAS Server 所在机器,该参数或 serviceUrl 至少有一个必须指定-->
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Filter</filter-name>
<url-pattern>/*</url-pattern>
<!--根目录下的所有进行过滤-->
</filter-mapping>
.......
</web-app>
3、测试CAS单点登录
1)在B机器IE上输入http://domainB:8080/casTest1/WelcomePage浏览器会弹出安全提示,接受后即转到 CAS 的登录页面。
2)登录成功后跳转至 WelcomePage页面
可到以看图 中地址栏里的地址多出了一个 ticket 参数,这就是 CAS 分配给当前应用的 ST(Service Ticket)。
3)再在同一个浏览器的地址栏中输入 http://domainC:8080/casTest2/WelcomePage ,系统不再提示用户登录,而直接出现如下图所示的页面,并且显示在 casTest1 中已经登录过的用户。
4)重新打开一个浏览器窗口,先输入 http://domainC:8080/casTest2/WelcomePage ,系统要求登录,在登录成功过后,正确显示 casTest2 的页面。之后再在地址栏重新输入 http://domainB:8080/casTest1/WelcomePage ,会直接显示 casTest1 的页面而无需再次登录。