流程梳理
- 配置安全证书
1.1 将证书导入到tomcat(客户端的tomcat)所使用的jdk密钥库中
1.2 将证书拷贝到指定目录(本例拷贝到tomcat的conf下) - 部署CAS服务端
2.1 指定服务端tomcat 所使用的jdk版本
2.2 开启tomcat HTTPS(CAS服务端的tomcat)
2.3 将CAS的war包拷贝到tomcat的webapp下
2.4 修改CAS配置文件deployerConfigContext.xml,使其支持不同的校验方式 - 部署CAS客户端
3.1 将所需jar包拷贝到web项目的lib下
3.2 修改web.xml配置文件
准备工作
- 准备如下软件包(我实在window 10 64位系统做的实验)
apache-tomcat-7.0.79.zip
jdk1.7.0_80
cas-server-webapp-4.0.0.war
cas-client-core-3.2.1.jar
commons-logging-1.2.jar
说明:需要3个tomcat,部署CAS中心服务器、客户端1号服务器、客户端2号服务器
- 配置hosts文件
文件位置:C:\Windows\System32\drivers\etc\hosts,在文件最下方加入
127.0.0.1 server.sso.com
127.0.0.1 app1.sso.com
127.0.0.1 app2.sso.com
说明:
server.sso.com --- CAS中心服务器,这个域名要与证书域名相同
app1.sso.com --- 客户端1号服务器
app2.sso.com --- 客户端2号服务器
开始部署
1. 配置安全证书
生成证书
使用cmd进入jdk的bin目录,之后输入
keytool -genkey -alias ssocas -keyalg RSA -keysize 1024 -keypass hopisso -validity 90 -keystore hopi.keystore -storepass hopisso
命令截图:
上图中的红色框必须与CAS中心服务器域名相同
导出证书
继续在cmd下输入
keytool -export -alias ssocas -keystore hopi.keystore -file ssocas.crt -storepass hopisso
命令截图:
导出证书
查看生成文件:
生成对应文件
导入证书
继续在cmd下输入
keytool -import -keystore E:\Dev\DevTools\Runtimes\Java\jdk1.7.0_80\bin\jre\lib\security\cacerts -file ssocas.crt -alias ssocas
说明:证书需要导入客户端tomcat所使用的jdk中
命令截图:
注意:输入密钥库口令:要输入changeit,它是jdk密钥库的默认密码,而不是我们之前指定的密码hopisso
拷贝证书
将证书文件hopi.keystore拷贝到将要部署CAS中心服务器的tomcat的conf目录下
操作截图:
开启HTTPS
编辑该目录下的server.xml文件,找到如下图位置:
修改成:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol"
keystorePass="hopisso" keystoreFile="/conf/hopi.keystore"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"/>
修改后截图:
指定Tomcat 所使用的jdk
修改tomcat \bin目录下的catalina.bat 与 setclasspath.bat
catalina.bat
setclasspath.bat
部署CAS服务端
将cas-server-webapp-4.0.0.war修改为cas.war并拷贝到CAS中心服务器的tomcat下的webapp下,启动CAS中心服务器的tomcat,点击进入CAS中心服务器
进入中心服务器
点高级后再点继续前往server.sso.com(不安全)
进入CAS中心服务器首页
在CAS中心服务器的tomcat中找到下图文件
可以看到我们CAS中心服务器的默认用户名和密码
输入对应的用户名和密码后可以看到如下图所示:
现在说明我们的CAS中心服务器已经部署成功
部署CAS客户端
拷贝jar包
将cas-client-core-3.2.1.jar和commons-logging-1.2.jar拷贝到我们的客户端项目中(这里我使用了tomcat默认的examples项目),见下图
配置端口
找到客户端tomcat服务器下的conf\server.xml文件
修改如下3个端口
原来是8005
原来是8080
原来是8009
修改web.xml
找到客户端tomcat的webapps\examples\WEB-INF\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>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
<init-param>
<param-name>casServerLoginUrl</param-name>
<param-value>https://server.sso.com:8443/cas/login</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://app1.sso.com:18080</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 该过滤器负责对Ticket的校验工作,必须启用它 -->
<filter>
<filter-name>CAS Validation Filter</filter-name>
<filter-class>
org.jasig.cas.client.validation.Cas10TicketValidationFilter</filter-class>
<init-param>
<param-name>casServerUrlPrefix</param-name>
<param-value>https://server.sso.com:8443/cas</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://app1.sso.com:18080</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Validation Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--
该过滤器负责实现HttpServletRequest请求的包裹,比如允许开发者通过HttpServletRequest的getRemoteUser()方法获得SSO登录用户的登录名,可选配置。
-->
<filter>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--
该过滤器使得开发者可以通过org.jasig.cas.client.util.AssertionHolder来获取用户的登录名。比如AssertionHolder.getAssertion().getPrincipal().getName()。
-->
<filter>
<filter-name>CAS Assertion Thread Local Filter</filter-name>
<filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CAS Assertion Thread Local Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
配置完成后,启动CAS中心服务器的tomcat,再启动客户端1号服务器的tomcat,在浏览器访问:http://app1.sso.com:18080/examples/servlets/servlet/HelloWorldExample看看是否跳转到了CAS认证界面,回车之后,会出现如下图:
观察会发现浏览器的地址栏中URL信息是这样的:
https://server.sso.com:8443/cas/login?service=http%3A%2F%2Fapp1.sso.com%3A18080%2Fexamples%2Fservlets%2Fservlet%2FHelloWorldExample
我想你已经知道什么意思了,由于你没有登录CAS中心服务器认证系统,CAS客户端1号拦截到你访问的客户端应用,首先进入到CAS中心服务器认证系统登录界面,同时URL后面加上你想访问的地址信息,当你登录成功后,CAS中心服务器会转向到你刚刚访问的地址,也就是:
http://app1.sso.com:18080/examples/servlets/servlet/HelloWorldExample;jsessionid=B99CBA08ADD2C4F1A8661195CD79F5DD
转向到这个地址之后,浏览器会显示如下内容:
上面这个内容,显示的就是你访问tomcat中的examples项目的一个servlet的返回结果。这里,如果你够细心的话,你会发现浏览器地址栏又多了一个内容,即多了一个jsessionid参数,这个就是CAS认证的原理所在,使用的是COOKIE机制。
按照上面的方法来配置客户端2号服务器
登出
在浏览器中输入连接:https://server.sso.com:8443/cas/logout可登出系统
扩展知识
数据库校验
如何配置用户名和密码通过数据库进行交互验证的呢?
- 需要将几个jar文件,放到CAS服务的lib目录下,我本地使用的jar版本分别是c3p0-0.9.1.2.jar、cas-server-support-jdbc-4.0.0.jar、mysql-connector-java-5.1.13-bin.jar,这3个缺一不可。将这3个jar放到CAS中心服务器的tomcat \webapps\cas\WEB-INF\lib目录下。
- 修改配置,支持mysql数据库交互验证编辑CAS中心服务器的tomcat \webapps\cas\WEB-INF\ deployerConfigContext.xml文件,你会看到有这样一段配置:
注释掉第二个entry配置,最终配置如下:
<constructor-arg>
<map>
<entry key-ref="proxyAuthenticationHandler" value-ref="proxyPrincipalResolver" />
<!-- 注释这个-->
<!--<entry key-ref="primaryAuthenticationHandler" value-ref="primaryPrincipalResolver" />-->
<!-- key-ref指定自己的本地数据库访问 -->
<entry key-ref="dbAuthHandler" value-ref="primaryPrincipalResolver"/>
</map>
</constructor-arg>
然后再在这个xml中新加入2个bean配置,如下:
<!-- 指定c3p0数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property ame="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/myProject?useUnicode=true&characterEncoding=UTF-8" />
<property name="user" value="root" />
<property name="password" value="root
</bean>
<!-- 访问本地数据库 -->
<bean id="dbAuthHandler"
class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler"
p:dataSource-ref="dataSource"
p:sql="SELECT u.`password` FROM `sec_user` u WHERE u.`account` = ?" />
现在,CAS已经支持数据库交互验证了,服务端tomcat也支持HTTPS协议访问,现在,我们来搭建客户端,实现多个客户端的单点登录。这里,我本地只使用2个tomcat客户端来测试,其实已经满足单点登录的要求了,至少2个应用。