第一篇博客,折腾了好久,以前没什么写博客的习惯,这次强行装个B
工程环境以及模块版本
- CentOS 6.3 x86_64
- Java 1.7
- CAS-server 4.0.0
- tomcat 6
- MySQL 5.1
- PHP 5.3.3
安装Java环境
Java应该都会装,懒得写了。。。
部署tomcat
安装1
$ yum install tomcat6.x86_64
启动1
$ service tomcat6 start
tomcat日志(/var/log/tomcat6/catalina.out)中有一个报错
安装OpenSSL
安装APR(Apache Portable Runtime)
安装tomcat-native
1
2
3
4$ tar zxvf tomcat-native.tar.gz
$ cd ./tomcat-native-1.1.33-src/jni/native
$ ./configure --with-apr=/usr/local/apr --with-java-home=/usr/local/java
$ make && make install加载APR的环境变量,编辑/etc/profile,添加
1
2LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/apr/lib
export LD_LIBRARY_PATH然后执行
1
$ source /etc/profile
重启tomcat,解决~
部署CAS-server
官网:http://developer.jasig.org/cas/
下载,上传服务器,解压1
$ cp ./cas-server-4.0.0/modules/cas-server-webapp-4.0.0.war /usr/share/tomcat6/webapps/cas.war
访问:http://cas.changg-1991.com:8080/cas/login
此时还没有使用https,所以会有一个警告,接下来给自己颁发证书
- 生成证书
1
$ keytool -genkey -alias changg-1991_cas -keyalg RSA -keystore /root/cas.keystore
把信息按照提示输入
导出证书
1
$ keytool -export -file /root/changg-1991_cas.crt -alias changg-1991_cas -keystore /root/changg-1991_cas.keystore
导入证书
这一步似乎不需要,我按照网上的办法导入提示:证书回复与秘钥库中的证书是相同的- 编辑tomcat配置文件server.xml

重启tomcat,日志中有一个报错
查了半天,原来是修改server.xml中SSL的属性protocol为org.apache.coyote.http11.Http11Protocol,参考
重启tomcat,之前的报错消失,出现新的问题
原来是权限问题,把keysore拷贝到/home/下面一个专门的文件夹,修改文件夹用户组权限为:tomcat.tomcat,同时修改server.xml中对应的配置,参考
重启tomcat,报错消失,还有几个没有什么卵用的报错暂时忽略,访问:https://cas.changg-1991.com:8443/cas/login?locale=zh_CN
弹出证书无效的提示,无视之,点击继续
默认的账号密码又坑了我一会儿,网上铺天盖地的说只要账号密码一致就可以登录,屁啊,那是哪年的版本了,终于找到一个靠谱的说法,我又去配置文件里找了一下果然账号是casuser,密码是Mellon(不知道Mellon是个什么鬼),成功登录
至此CAS-server部署完毕~
部署CAS-client
官网:http://developer.jasig.org/cas-clients/
搞了一会儿,想了想不对,我最终是用PHP实现这个客户端,所以去github上搜了一下“cas php”找到:https://github.com/Jasig/phpCAS
工程下载下来并没有文档和demo,囧,用sourcetree clone了一份,有了,测试一下,访问:http://www.changg-1991.com/phpCAS/docs/examples/example_gateway.php
500错误,需要重命名配置文件为config.php
编辑config.php,配置$cas_host、$cas_context和$cas_port为刚刚搭建好的CAS-server的相关值,保存退出重新访问,又报500错误,apache的error_log报错
原来是缺少php-xml模块,yum装上,重启apache,再次访问
点击login跳转到
输入用户名密码点击登录
点击Logout
PHP的CAS-client搭建成功~
配置CAS连接MySQL进行认证
拷贝cas-server-support-jdbc-4.0.0.jar1
$ cp /root/cas-server-4.0.0/modules/cas-server-support-jdbc-4.0.0.jar /usr/share/tomcat6/webapps/cas-server-webapp-4.0.0/WEB-INF/lib/
下载mysql-connector-java,官网:http://dev.mysql.com/downloads/connector/j/
上传服务器1
$ cp /root/mysql-connector-java-5.1.37-bin.jar /usr/share/tomcat6/webapps/cas-server-webapp-4.0.0/WEB-INF/lib/
编辑cas/WEB-INF/deployerConfigContext.xml,注释掉
与注释同等级的地方增加标签:1
2
3
4
5
6
7
8
9
10
11
12<bean id="mysqlAuthenticationHandler"
class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
<property name="sql" value="select password from foodies where foodname=?" />
<property name="dataSource" ref="dataSource" /></property>
</bean>
<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/cas_auth</value></property>
<property name="username"><value>root</value></property>
<property name="password"><value>123456</value></property>
</bean>
接下来在下面还需要进行一个修改
数据库建库cau_auth
建表foodies1
2
3
4
5
6
7
8
9
10
11
12
13CREATE TABLE `foodies` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`foodname` varchar(50) NOT NULL default '',
`password` varchar(100) NOT NULL default '',
`salt` varchar(100) NOT NULL default '',
`zh_name` varchar(20) NOT NULL default '',
`email` varchar(100) NOT NULL default '',
`status_flag` tinyint(4) NOT NULL DEFAULT 0,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`),
UNIQUE KEY `index_foodname` (`foodname`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
在数据库中插入一条数据,重启tomcat,访问:http://www.changg-1991.com/phpCAS/docs/examples/example_gateway.php
用插入的账号密码去登录,验证OK,此时密码是明文的,接下来自定义加密方式
CAS自定义加密方式
这个地方是最最最蛋疼的,搞了好久,网上的东西不是CAS-server版本和我用的不一样,就是根本用不了,要不还有就简简单单的一个MD5加密,本着对系统负责任的态度,决定搞的彻底一些,用sha1(salt+md5(password))的模式,这块最后做下来并没有很复杂的改动,说到底就是一个耐心和坚持,还好最终搞出来了,和大家分享一下
首先修改deployerConfigContext.xml
1
<property name="sql" value="select salt, password from foodies where foodname=?" />
重写cas-server-support-jdbc/src/main/java/org/jasig/cas/adaptors/jdbc/QueryDatabaseAuthenticationHandler.java
这个就是cas-server-support-jdbc.jar的源码,在下载下来的CAS-server包里有1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68/**
* 新建一个内部类Foodies
*/
private class Foodies {
private String salt;
private String password;
public void setSalt(final String salt) {
this.salt = salt;
}
public void setPassword(final String password) {
this.password = password;
}
public final String getSalt() {
return this.salt;
}
public final String getPassword() {
return this.password;
}
}
/**
* 继承RowMapper,重写mapRow的方法
*/
private class FoodiesRowMapper implements RowMapper {
@Override
public Object mapRow(ResultSet resultSet, int value) throws SQLException {
Foodies foodies = new Foodies();
foodies.setSalt(resultSet.getString("salt"));
foodies.setPassword(resultSet.getString("password"));
return foodies;
}
}
@Override
protected final HandlerResult authenticateUsernamePasswordInternal(final UsernamePasswordCredential credential)
throws GeneralSecurityException, PreventedException {
final String username = credential.getUsername();
// final String encryptedPassword = this.getPasswordEncoder().encode(credential.getPassword());
final String password = this.getPasswordEncoder().encode(credential.getPassword());
try {
// final String dbPassword = getJdbcTemplate().queryForObject(this.sql, String.class, username);
// 这个地方和源代码不同的地方就在于,查出来的是一个RowMapper类的对象,可以携带多个值返回,对应上面配置中的select salt, password from foodies
final Foodies foodies = (Foodies)getJdbcTemplate().queryForObject(this.sql, new FoodiesRowMapper(), username);
final String salt = foodies.getSalt();
final String dbPassword = foodies.getPassword();
// 自定义的加密方式,直接替换之前的明文比较的办法,md5和sha1是用messageDigest类实现的方法
final String encryptedPassword = this.sha1(salt + this.md5(password));
if (!dbPassword.equals(encryptedPassword)) {
throw new FailedLoginException("Password does not match value on record.");
}
} catch (final IncorrectResultSizeDataAccessException e) {
if (e.getActualSize() == 0) {
throw new AccountNotFoundException(username + " not found with SQL query");
} else {
throw new FailedLoginException("Multiple records found for " + username);
}
} catch (final DataAccessException e) {
throw new PreventedException("SQL exception while executing query for " + username, e);
} catch (final NoSuchAlgorithmException ignored) {
// 这个exception是md5和sha1抛出来的
}
return createHandlerResult(credential, new SimplePrincipal(username), null);
}
然后打jar包1
$ jar cvf cas-server-support-jdbc-4.0.0.jar cas-server-support-jdbc/
用这个jar包去覆盖cas/WEB-INF/lib/cas-server-support-jdbc-4.0.0.jar
重启tomcat报了无数行的错误。。。我并不会java,都是边查边写的,我一直以为是我代码写错了,改了又改,直到问了我们安卓@大锅,他告诉我这是maven打的包,这才又有一丝希望,累觉不爱。。。
mac安装maven环境1
$ brew install maven
继续打包,cd到cas-server-support-jdbc源码下面1
$ mvn package
打了很久很久,很多downloading。。。,最后失败了,又和@大锅调了半天,改了一下pom.xml1
$ mvn clean package -DskipTests=true -Dlicense.skip=true
终于成功了!
修改数据库中password字段为sha1(“yan”+md5(“123456”))
重启tomcat,访问:http://www.changg-1991.com/phpCAS/docs/examples/example_gateway.php
尝试用root和123456去登录,成功!
CAS登录获取更多用户信息
编辑deployerConfigContext.xml,注释掉
在同一级的位置新增1
2
3
4
5
6
7
8
9
10
11
12
13
14<bean class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao" id="attributeRepository">
<constructor-arg index="0" ref="dataSource"/>
<constructor-arg index="1" value="select foodname, email from foodies where {0}"/>
<property name="queryAttributeMapping">
<map>
<entry key="username" value="foodname"/>
</map>
</property>
<property name="resultAttributeMapping">
<map>
<entry key="email" value="email"/>
</map>
</property>
</bean>
在下面还需要做一个修改
编辑cas/WEB-INF/view/jsp/protocol/2.0/casServiceValidationSuccess.jsp
客户端用phpCAS::getAttribute(‘email’)方法获取额外信息
重启tomcat,访问:http://www.changg-1991.com/phpCAS/docs/examples/example_gateway.php
返回页面
Mission Compete!
接下来要做的事
- 防止SQL注入
- 更改登录界面
CAS防止sql注入暂时用一个非常严格(select)的本机连接授权给解决了
参考
http://www.micmiu.com/enterprise-app/sso/sso-cas-sample/
http://www.micmiu.com/enterprise-app/sso/cas-server-auth-db/
http://www.kafeitu.me/sso/2010/11/05/sso-cas-full-course.html
http://showerlee.blog.51cto.com/2047005/1265405
http://www.tuicool.com/articles/7ZbEju
http://www.mkyong.com/spring/spring-jdbctemplate-querying-examples/
http://pkaq.github.io/2015/01/14/2015-01-14-CAS/
著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处
作者:changg-1991
链接:http://blog.changg-1991.com/2015/11/13/CAS搭建-MySQL认证-自定义加密-PHP客户端