上一章搭建了单点登录的基本搭建,但是它的用户名和密码是写死的。显然,这样是不行的,用户名密码一般都存放在数据库中。本文将介绍如何让CAS支持MySQL存储用户名和密码。
此文档代码GitHub地址
CREATE TABLE `sys_user` (
`username` varchar(20) NOT NULL,
`password` varchar(36) NOT NULL,
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`nickname` varchar(20) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username_` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
/*Data for the table `sys_user` */
insert into `sys_user`(`username`,`password`,`id`,`nickname`) values ('admin','password',1,'admin');
org.apereo.cas
cas-server-support-jdbc
${cas.version}
org.apereo.cas
cas-server-support-jdbc-drivers
${cas.version}
mysql
mysql-connector-java
5.1.36
##
# CAS Authentication Credentials 默认的静态用户名和密码配置
# 注释默认账号密码
#cas.authn.accept.users=casuser::Mellon
#添加jdbc认证
cas.authn.jdbc.query[0].sql=SELECT * FROM sys_user WHERE username =?
#哪一个字段作为密码字段
cas.authn.jdbc.query[0].fieldPassword=password
#配置数据库连接
cas.authn.jdbc.query[0].url=jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false
cas.authn.jdbc.query[0].dialect=org.hibernate.dialect.MySQLDialect
#数据库用户名
cas.authn.jdbc.query[0].user=root
#数据库密码
cas.authn.jdbc.query[0].password=123456
#mysql驱动
cas.authn.jdbc.query[0].driverClass=com.mysql.jdbc.Driver
现在数据库中的密码是明文存储的,一般数据库中的密码是MD5加密后再保存的,所以需要对密码进行处理
#登录密码配置加密策略
cas.authn.jdbc.query[0].passwordEncoder.type=DEFAULT
cas.authn.jdbc.query[0].passwordEncoder.characterEncoding=UTF-8
cas.authn.jdbc.query[0].passwordEncoder.encodingAlgorithm=MD5
启动后用admin password登录提示认证信息无效。插入一条新的数据库记录
insert into `sys_user`(`username`,`password`,`id`,`nickname`) values ('zhangsan','5f4dcc3b5aa765d61d8327deb882cf99',2,'张三');
步骤5只是对密码进行了简单的加密,推荐使用盐值
修改application.properties,在上面的基础上,再添加如下代码,可以共存
#2.对登录密码盐值处理。如果两种方式都配置的话,默认先用普通MD5验证,如果验证失败,打印异常日志,然后再使用加盐方式验证。
#加密迭代次数
cas.authn.jdbc.encode[0].numberOfIterations=2
#该列名的值可替代上面的值,但对密码加密时必须取该值进行处理
cas.authn.jdbc.encode[0].numberOfIterationsFieldName=
#盐值固定列
cas.authn.jdbc.encode[0].saltFieldName=username
#静态盐值
cas.authn.jdbc.encode[0].staticSalt=.
cas.authn.jdbc.encode[0].sql=SELECT * FROM sys_user WHERE username =?
#对处理盐值后的算法
cas.authn.jdbc.encode[0].algorithmName=MD5
cas.authn.jdbc.encode[0].passwordFieldName=password
cas.authn.jdbc.encode[0].expiredFieldName=expired
cas.authn.jdbc.encode[0].disabledFieldName=disabled
#数据库连接
cas.authn.jdbc.encode[0].url=jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false
cas.authn.jdbc.encode[0].dialect=org.hibernate.dialect.MySQL5Dialect
cas.authn.jdbc.encode[0].driverClass=com.mysql.jdbc.Driver
cas.authn.jdbc.encode[0].user=root
cas.authn.jdbc.encode[0].password=123456
利用下面的帮助类生成盐值
package com.weisi.veems.frame.utils;
import org.apache.shiro.crypto.hash.ConfigurableHashService;
import org.apache.shiro.crypto.hash.DefaultHashService;
import org.apache.shiro.crypto.hash.HashRequest;
import org.apache.shiro.util.ByteSource;
/**
* @author:luomouren
* @description:
* @dateTime: created in 2018-10-31 14:50
* @modified by:
**/
public class PasswordSalt {
/**
* 静态盐值
*/
private static final String STATIC_SALT = ".";
/**
* 对处理盐值后的算法
*/
private static final String ALGORITHM_NAME = "MD5";
/**
* 对登录密码盐值处理
* @param username 账号
* @param password 密码
* @throws Exception
*/
public static String encryPassword(String username,String password) throws Exception {
ConfigurableHashService hashService = new DefaultHashService();
// 静态盐值
hashService.setPrivateSalt(ByteSource.Util.bytes(STATIC_SALT));
hashService.setHashAlgorithmName(ALGORITHM_NAME);
// 加密迭代次数
hashService.setHashIterations(2);
HashRequest request = new HashRequest.Builder()
.setSalt(username)
.setSource(password)
.build();
String res = hashService.computeHash(request).toHex();
System.out.println(res);
return res;
}
public static void main(String[] args) {
try {
PasswordSalt.encryPassword("lisi","password");
} catch (Exception e) {
e.printStackTrace();
}
}
}
往数据库中插入记录
insert into `sys_user`(`username`,`password`,`id`,`nickname`) values ('lisi','d8ab2b68f1a4af359e86928302585826',3,'李四');
利用zhangsan password 和 lisi password登录验证成功