本文共 4466 字,大约阅读时间需要 14 分钟。
原文地址,转载请注明出处: ©
上一章搭建了单点登录的基本骨架,但是它的用户名和密码是写死的。显然,这样是不行的,用户名密码一般都存放在数据库中。本文将介绍如何让CAS支持MySQL存储用户名和密码。
#表结构使用的是之前shiro用户表DROP TABLE IF EXISTS `user_info`;CREATE TABLE `user_info` ( `uid` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(50) DEFAULT '' COMMENT '用户名', `password` varchar(256) DEFAULT NULL COMMENT '登录密码', `name` varchar(256) DEFAULT NULL COMMENT '用户真实姓名', `id_card_num` varchar(256) DEFAULT NULL COMMENT '用户身份证号', `state` char(1) DEFAULT '0' COMMENT '用户状态:0:正常状态,1:用户被锁定', PRIMARY KEY (`uid`), UNIQUE KEY `username` (`username`) USING BTREE, UNIQUE KEY `id_card_num` (`id_card_num`) USING BTREE) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
#插入用户信息表INSERT INTO user_info(uid,username,`password`,`name`,id_card_num) VALUES (null,'admin','123456','超哥','133333333333333333');
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.authn.accept.users=casuser::Mellon
#添加jdbc认证cas.authn.jdbc.query[0].sql=SELECT * FROM user_info WHERE username =?#那一个字段作为密码字段cas.authn.jdbc.query[0].fieldPassword=password#配置数据库连接cas.authn.jdbc.query[0].url=jdbc:mysql://127.0.0.1:3306/testshiro?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=falsecas.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
现在启动程序,使用admin/123456登录成功,可以从数据库获取信息登录,但是一般情况,是不会直接在数据库中存储明文密码的,下面我们来配置MD5加密。
#配置加密策略cas.authn.jdbc.query[0].passwordEncoder.type=DEFAULTcas.authn.jdbc.query[0].passwordEncoder.characterEncoding=UTF-8cas.authn.jdbc.query[0].passwordEncoder.encodingAlgorithm=MD5
这个时候再次使用账号admin 密码123456登录已经无法认证通过了,将123456的MD5密文e10adc3949ba59abbe56e057f20f883e放入数据库,这个时候再登录就可以了。
上一步只是对密码进行了简单的加密,两个帐号有可能相同的值,就能判断出密码是一致的,但通过此方案,大大增加了难度,所以安全系数也高了许多,推荐使用策略。 在上面的基础上,再添加如下代码,可以共存,:
#加密迭代次数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 user_info WHERE username =?#对处理盐值后的算法cas.authn.jdbc.encode[0].algorithmName=MD5cas.authn.jdbc.encode[0].passwordFieldName=passwordcas.authn.jdbc.encode[0].expiredFieldName=expiredcas.authn.jdbc.encode[0].disabledFieldName=disabled#数据库连接cas.authn.jdbc.encode[0].url=jdbc:mysql://127.0.0.1:3306/testshiro?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=falsecas.authn.jdbc.encode[0].dialect=org.hibernate.dialect.MySQL5Dialectcas.authn.jdbc.encode[0].driverClass=com.mysql.jdbc.Drivercas.authn.jdbc.encode[0].user=rootcas.authn.jdbc.encode[0].password=123456
注意:
如果两种方式都配置的话,默认先用普通MD5验证,如果验证失败,打印异常日志,然后再使用加盐方式验证。
package com.springboot.test.shiro;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;import org.junit.Test;/** * @author: wangsaichao * @date: 2018/7/7 * @description: */public class PasswordSaltTest { private String staticSalt = "."; private String algorithmName = "MD5"; private String encodedPassword = "123456"; private String dynaSalt = "test"; @Test public void test() throws Exception { ConfigurableHashService hashService = new DefaultHashService(); hashService.setPrivateSalt(ByteSource.Util.bytes(this.staticSalt)); hashService.setHashAlgorithmName(this.algorithmName); hashService.setHashIterations(2); HashRequest request = new HashRequest.Builder() .setSalt(dynaSalt) .setSource(encodedPassword) .build(); String res = hashService.computeHash(request).toHex(); System.out.println(res); }}
#密码是通过上面的PasswordSaltTest 生成的INSERT INTO user_info(uid,username,`password`,`name`,id_card_num) VALUES (null,'test','ed0290f05224a188160858124a5f5077','超哥哥','166666666666666666');
使用admin/123456登录成功(普通MD5可用)
使用test/123456登录成功(加盐密码可用)