用CAS框架实现单点登录
昨天刚学了用cas框架来实现Java web的单点登录,通过找资料,整合了几篇博文,再加上自己的理解,写了这篇博文。
一.准备工作
1.开发环境
apache-tomcat-7.0.32 我的安装路径:E:\apache-tomcat-7.0.32
jdk1.7.0_55 我的安装路径:E:\Java\jdk1.7.0_55
注意:安装路径最好不要出现空格,因为这样在编译或者做其他操作的时候可能会出现无法定位的情况
2.下载jar包
Cas服务端:cas-server-3.4.10-release.zip 下载址:https://www.apereo.org/cas/download
Cas客户端:cas-client-3.2.1-release.zip 下载址:http://downloads.jasig.org/cas-clients/
二.安装证书
1.用JDK自带的keytool生成证书
打开cmd窗口,输入命令:keytool -genkey -alias casserver -keyalg RSA -keystore E:\keys\caskey,其中-alias是指定别名为casserver(自定义,最好有意义),-keyalg指定RSA算法,-keystore指定文件生成的路径以及文件名(文件名caskey可以自定义)。
上面命令输入完成后按回车键出现下面窗口,按提示输入密钥库口令就可以了。
注意:密钥库口令最少为6位字符,输入的密钥库口令不会回显,输入后按回车键再输入确认口令就可以了。
完成了上面的操作后会出现下面一系列问题(问题回答完毕才显示下一个问题)。
注意:您的名字与姓氏是什么?这个问题不要随便填写,一定不能为localhost,最好是写成一个域名。后面的“输入 <casserver> 的密钥口令”这个是必须相同的,直接按回车键就可以了。
上面的操作完成后会在E:\keys\下生成caskey文件。如下:
至此,证书已经安装完毕,打开C:\Windows\System32\drivers\etc\hosts文件,把上面“您的名字与姓氏是什么?”这个问题的回答的答案映射成主机,如下:
2.导出证书
在cmd窗口输入命令:keytool -export -file E:\keys\cas.crt -alias casserver -keystore E:\keys\caskey。
注意:这里的-alias指定的别名与上面生成指定别名要相同,密钥库口令也要相同,否则证书导出失败。
完成以上操作后,会在E:\keys\下生成文件cas.crt,如下:
3.将证书导入到JDK中
在cmd窗口中输入命令:cd /d E:\Java\jdk1.7.0_55\jre\lib\security(注意,跨分区需要参数/d,否则无法进入),进入jdk中的security目录,然后输入命令:keytool -import -keystore cacerts -file E:\keys\cas.crt -alias casserver,按回车键后按提示输入并执行结果如下:
完成以上操作后在E:\Java\jdk1.7.0_55\jre\lib\security下会生成cacerts文件,如下:
三.https访问cas
进入打开E:\apache-tomcat-7.0.32\conf下的server.xml文件,取消“<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"maxThreads="150" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" />”的注释,并添加如下红框部分内容,结果如下:
注意:其中https的默认端口是443,访问时不需要输入断开即可访问,当设为8443时需要再加上端口号8443才可以访问。keystoreFile为生成证书时产生的caskey文件,keystorePass为生成证书时设置的密钥库口令。
把cas-server-3.4.10-release.zip解压,然后再把解压后cas-server-3.4.10\modules下的cas-server-webapp-3.4.10.war解压,把名字改成cas,并复制到E:\apache-tomcat-7.0.32\webapps下,如下:
至此,在firefox浏览器中输入:https://sso.czh.com/cas并进行访问,则会出现如下页面:
这是因为证书是我们自己签的而不被信任,把它添加例外就可以访问了,如下:
确认安全例外后页面会跳转到cas server验证页面:
用户名和密码都输入admin(输入用户名和密码即可访问)后,跳转到提示“登录成功”的页面,如下:
至此,可以通过https访问cas服务器。
四.配置通过数据库和CAS系统实现单点登录
1.服务端配置
1).把cas-server-3.4.10\modules下的cas-server-support-jdbc-3.4.10.jar复制到部署在tomcat里的cas\WEB-INF\lib下,然后下载mysql-connector-java-5.1.8-bin.jar并复制到cas项目里面。
2).创建数据库test,并创建表user(包含自动id,username,password),完成后插入数据
3).修改部署在tomcat里的cas\WEB-INF目录下的deployerConfigContext.xml文件,把“<bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />”注释掉,然后添加下面代码:
<bean class="org.jasig.cas.adaptors.jdbc.SearchModeSearchDatabaseAuthenticationHandler"
abstract="false" lazy-init="default" autowire="default">
<property name="tableUsers"><value>user</value></property>
<property name="fieldUser"><value>username</value></property>
<property name="fieldPassword"><value>password</value></property>
<property name="dataSource" ref="dataSource" />
</bean>
注意:上面这段配置文件主要是添加对用户名和密码的校验工作,常用的有三种校验方式
(1).SimpleTestUsernamePasswordAuthenticationHandler
这个就是默认的简单的用户名密码校验,只要用户名和密码相同就能登录。
(2).QueryDatabaseAuthenticationHandler
这个是用select语句来验证,具体配置文件可以参考网上写的。
(3).SearchModeSearchDatabaseAuthenticationHandler
这个是通过指定表盒字段来连接数据库,本文配置文件使用的方法。
最后在文件末尾加上如下代码:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property>
<property name="url"><value>jdbc:mysql://localhost:3306/osmdb</value></property>
<property name="username"><value>my580236</value></property>
<property name="password"><value>123456</value></property>
</bean>
<bean id="MD5PasswordEncoder" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder">
<constructor-arg index="0"><value>MD5</value></constructor-arg>
</bean>
至此,cas的服务端,我们就配置好了。
2.客户端配置
创建两个项目,分别为casfirst和cassecond,修改它们的web.xml文件为:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<display-name></display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 拦截项目进入cas server验证界面 -->
<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://sso.czh.com:443/cas/</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://localhost:80</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Authentication Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 这里没有配置的话登录,index.jsp配置的获取当前登录的用户名就会报空指针异常,具体什么作用我也不清楚 -->
<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://sso.czh.com:443/cas</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://localhost:80</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Validation Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
修改index.jsp为
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ page import="org.jasig.cas.client.util.AbstractCasFilter"%>
<%@ page import="org.jasig.cas.client.validation.Assertion"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%
Assertion assertion1=(Assertion)session.getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION);
String username = assertion1.getPrincipal().getName();
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>cas项目一</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
当前登录的用户是:<%=username%> </br>
这是casfirst项目,<a href="http://localhost:80/cassecond/index.jsp?value=casfirst">进入cassecond项目,并携带参数value=casfirst </a>
</body>
</html>
把cas、casfirst、cassecond三个项目都部署到tomcat,然后启动,访问项目一:calhost/casfirst,会自动跳转到cas server的验证页面,这时输入数据库里的用户名和密码,验证成功则会进入到casfirst项目的index.jsp页面,并把当前登录的用户名带过去,通过页面显示的超链接进入cassecond项目,登录casfirst项目的用户名也能带过来。访问项目二:calhost/cassecond与一一样。
五.总结
至此,用cas实现单点登录的到此结束,本实例没有实际的意义,仅供初学者了解用cas实现单点登录的配置流程,由于我也是初学者,所以对于里面的一些配置理解不到位请不要吐槽,有问题的提出来大家一起讨论学习。