到下载页面下载以下3个zip包:
第一个,CAS Server,这个是CAS的服务器端(当前最新版本是3.5.1)
服务端下载地址:http://www.jasig.org/cas/download
第二个,JA-SIGCAS Java Client,这个是官方开发的CAS的客户端,用于单点退出。特别注意事项:当前只有3.1.2及以上版本支持单点退出(当前最新版本是3.2.1)
客服端下载地址:http://downloads.jasig.org/cas-clients/
第三个,Yale CAS Client,这个是耶鲁大学开发的CAS的客户端,用于单点登录,不支持单点退出(当前最新版本是2.0.11)
1.下载cas-server和cas-client(可选,建议使用)
http://www.yale.edu/tp/cas/cas-server-2.0.12.zip
http://www.yale.edu/tp/cas/cas-client-2.0.11.zip (下面我使用的是cas-client-2.0.11)
Tomcat 下配置CAS,首先要让Tomcat支持SSL,要产生证书之类的,命令简单介绍如下:
生成密匙:
keytool -genkey -alias tomcat -keystore ./mykeystore -keyalg RSA -validity 2000
-keyalg RSA 指的是采用的RSA算法
输入密码:danding
姓名:据说要输入服务器域名,本机测就localhost吧
会在该目录下生成mykeystore文件
导出证书,命令
keytool -export -alias tomcat -keystore ./mykeystore -file server.crt
密码和上面一样
会在该目录下生成一个server.crt 文件
然后把该证书导入jdk下
以我自己的mac为例
keytool -import -file server.crt -keystore /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home/lib/security/cacerts
导入到security目录下
配置tomcat 服务器端:
修改tomcat里的server.xml配置文件,讲一下一段去掉注释(正常情况下是注掉的),并加上keystoreFile="c:/resource/cas/mykeystore ",keystorePass="danding"
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="mykeystore"
keystorePass="danding"/>
最好把mykeystore文建移到tomcat目录下,在mac下总是在写的路径下自动加上tomcat的路径,例如.../tomcat/mykeystore
将我们下载的cas-server包解压modules目录下有个cas-server的打包文件,放到tomcat的webapps目录下
启动tomcat后,输入http://localhost:8080/cas/login和https://localhost:8443/cas/login都可以访问的
配置tomcat客户端:
端口改为8180就行了
新建一个grails项目 名字:testCase1
引入包:cas-client-2.0.11\cas-client-2.0.11\java\lib\casclient.jar(用于单点登陆)
引入包:cas-client-3.2.1-release\cas-client-3.2.1\modules目录下的cas-client-core-3.2.1.jar(用于单点退出)
引入包:cas-client-3.2.1-release\cas-client-3.2.1\modules目录下的commons-logging-1.1.jar(用于单点退出)
在testCase1的web.xml中增加如下代码:
grails项目下找不到web.xml,用grails install-templates命令生成就有了
然后在web.xml文件中写过滤器的配置就可以了!!!
<!-- 用于单点退出 -->
<listener>
<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener<stener-class>
<stener>
<filter>
<filter-name>CAS Single Sign Out Filter</filter-name>
<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter>
<!-- 用于单点登录 -->
<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://localhost:8443/cas/login</param-value>
<!--这里的server是服务端的IP-->
</init-param>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>
<param-value>https://localhost:8443cas/serviceValidate</param-value>
<!--这里的ServerName是服务端的主机名也就是CN-->
</init-param>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>
<param-value>localhost:8180</param-value>
<!--client:port就是需要cas需要拦截的地址和端口,一般就是这个tomcat所启动的ip和port-->
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Single Sign Out Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--下面的filter根据需要配置-->
<!--
该过滤器负责实现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>
<!-- 自动根据单点登录的结果设置本系统的用户信息 -->
<filter>
<display-name>AutoSetUserAdapterFilter</display-name>
<filter-name>AutoSetUserAdapterFilter</filter-name>
<filter-class>
com.cas.client.filter.AutoSetUserAdapterFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>AutoSetUserAdapterFilter</filter-name>
<url-pattern>/*</url-pattern> </filter-mapping>
AutoSetUserAdapterFilter类设置登录用户session信息代码如下:
public class AutoSetUserAdapterFilter implements Filter{
public void destroy() {
}
/**
* 过滤逻辑:首先判断单点登录的账户是否已经存在本系统中,
* 如果不存在使用用户查询接口查询出用户对象并设置在Session中
*/
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
// _const_cas_assertion_是CAS中存放登录用户名的session标志
Object object = httpRequest.getSession().getAttribute("_const_cas_assertion_");
if (object != null) {
Assertion assertion = (Assertion) object;
String loginName = assertion.getPrincipal().getName();
System.out.println("登录名为:"+loginName);
// 接下来在本业务系统中根据用户名获取用户对象,判断session中是否存在,
// 如果不存在,则获取用户对象保存到session中,否则直接获取用户对象。
}
chain.doFilter(request, response);
}
public void init(FilterConfig filterConfig) throws ServletException {
} }
测试:同时将testCase1和cas发布一下,访问http://localhost:8180/testCase1,将自动跳转到服务端的登录页面,填写相同的用户名和密码,则成功登录并跳转回客户端的。
测试单点登录和退出:
再创建grails工程,名字:testCase2
同时部署server,testCase1,testCase2
测试1:访问testCase1,登录后可以直接访问testCase2
测试2:访问testCase2,登录后可以直接访问testCase1
测试3:登录testCase1,退出后可以不可访问testCase1和testCase2
如何退出?访问https://localhost:8443/cas/logout就退出了。
注意事项:访问形如http:// localhost:8080/cas_server/logout,这种通过http方式访问退出是不行的!!因为你不通过https来注销,CAS Server怎么"杀"掉它通过https发给你的TGC Cookie?
至此,基本完成单点登录和退出功能。
如果跳转的时候出现了unable to find valid certification path to requested target错误怎搞?
该错误是机子有多个jdk版本,运行多个项目时使用的可能不是同一个版本,解决方法是,把证书导入到使用的jdk版本里。
通过直接访问数据库定制密码验证
1.新建数据库cas,在建一个user表
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`username` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=gbk;
INSERT INTO `user` VALUES ('1', '1');
2.加入包到webapps\cas\WEB-INF\lib:
mysql-connector-java-5.1.5-bin.jar
cas-server-support-jdbc-3.3.1.jar(来自于cas-server-3.3.1.zip)
spring-jdbc-2.5.5.jar
3. 在webapps\cas\WEB-INF\deployerConfigContext.xml文件中加入dateSource的Bean
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" destroy-method="close">
<property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property>
<property name="url"><value>jdbc:mysql://localhost:3306/cas</value></property>
<property name="username"><value>root</value></property>
<property name="password"><value></value></property>
</bean>
4. 在deployerConfigContext.xml文件中
注释掉:
<bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePassword
AuthenticationHandler" />
换成:
<bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
<property name="dataSource" ref="casDataSource" />
<property name="sql" value="select password from user where username=?" />
<property name="passwordEncoder" ref=" passwordEncoder "/>
</bean>
安全证书到期了怎么办?
只要重新向jdk中导入证书就行了
inmatoMacBook-Pro:sso root# keytool -import -file server.crt -keystore /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home/lib/security/cacerts输入密钥库口令:
所有者: CN=localhost, OU=nala, O=nala, L=杭州市, ST=浙江省, C=cn
发布者: CN=localhost, OU=nala, O=nala, L=杭州市, ST=浙江省, C=cn
序列号: 60e4240a
有效期开始日期: Wed Nov 07 16:54:06 CST 2012, 截止日期: Mon Apr 30 16:54:06 CST 2018
证书指纹:
MD5: 94:73:8A:06:7B:4C:DF:09:5C:D4:F0:CE:9D:2C:DC:9E
SHA1: E5:F1:73:9F:FD:04:33:85:7F:AD:7F:2E:51:12:63:60:CC:8E:4C:C4
SHA256: B5:70:1C:04:97:99:CA:2B:9D:C6:B7:BF:04:29:7D:CB:E9:3E:87:00:7B:C9:0E:4F:2B:93:3D:88:4D:81:85:E8
签名算法名称: SHA256withRSA
版本: 3
扩展:
#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: F8 B5 EE B4 7F 5E 01 53 06 D2 79 01 10 43 51 AE .....^.S..y..CQ.
0010: D8 23 E7 0A .#..
]
]
是否信任此证书? [否]: y
证书已添加到密钥库中
mac下亲测,可行