本章节的内容为JDBC认证,查找数据库进行验证,其中包括:
在不同公司,可能有很多业务需求或者架构不一样导致我们实现验证的方式不一样,那么cas为我们提供了很多认证的模式(当然也可以自定义),其中常用的有:
当然也有一些公司或者企业也非常的变态,如:
cas支持jdbc校验方案:
select * from table_users where username=?
)可判断有效等select count(x) from tables_users where username = ? and password=?
),不可判断有效期,若数量大于0则成功采用mysql数据库存储用户数据。
修改pom.xml
sso-server/pom.xml:
org.apereo.cas
cas-server-support-jdbc
${cas.version}
mysql
mysql-connector-java
5.1.16
sys_user:
create table sys_user
(
id int not null auto_increment,
username varchar(40),
password varchar(200),
expired int comment '1为过期 需要修改密码',
disable int comment '1为不可用,禁用',
email varchar(200),
primary key (id)
);
根据sql给予用户名进行查询,根据密码字段进行鉴定(
select * from sys_user where username=?
)
程序新增配置
##
# CAS Authentication Credentials
#
#cas.authn.accept.users=casuser::Mellon
#Query Database Authentication 数据库查询校验用户名开始
#查询账号密码sql,必须包含密码字段
cas.authn.jdbc.query[0].sql=select * from sys_user where username=?
#指定上面的sql查询字段名(必须)
cas.authn.jdbc.query[0].fieldPassword=password
#指定过期字段,1为过期,若过期不可用
cas.authn.jdbc.query[0].fieldExpired=expired
#为不可用字段段,1为不可用,需要修改密码
cas.authn.jdbc.query[0].fieldDisabled=disabled
#数据库方言hibernate的知识
cas.authn.jdbc.query[0].dialect=org.hibernate.dialect.MySQLDialect
#数据库驱动
cas.authn.jdbc.query[0].driverClass=com.mysql.jdbc.Driver
#数据库连接
cas.authn.jdbc.query[0].url=jdbc:mysql://localhost/sso?characterEncoding=utf8
#数据库用户名
cas.authn.jdbc.query[0].user=root
#数据库密码
cas.authn.jdbc.query[0].password=123456
#Query Database Authentication 数据库查询校验用户名结束
以上配置,如驱动,查询数据库等等需要根据不同的场景进行调整
常用单向加密算法:MD5、SHA、HMAC。
一般我们常用的加密算法就这几种。在JDBC认证中我们也可以选择配置加密算法,加密算法一般为上面的三种,MD5、SHA、HMAC,加密类型为NONE|DEFAULT|STANDARD|BCRYPT|SCRYPT|PBKDF2
这几种,我们在配置文件中选择加密类型,指定加密算法。
前面配置不变指定JDBC配置,后面的配置为密码加密策略,配置如下:
#默认加密策略,通过encodingAlgorithm来指定算法,默认NONE不加密
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/123):
然后我们启动应用。当我们运行起CAS,输入原来的用户名和密码admin/123456
,并不能登录,因为我们更改密码验证为MD5加密模式了。将123456
使用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/sso?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
加密生成类:
//固定盐生成类
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);
}
}
使用test/123456登录成功(加盐密码可用)
除此之外如果我们要自定义加密类型,就需要实现org.springframework.security.crypto.password.PasswordEncoder
接口,并且把类名配置在passwordEncoder.type
。
这种方式我们在这里就不做尝试了,接下来我们结合SpringSecurity提供的加密方法,完成自定义认证校验策略(推荐使用
)