shiro—用户登录认证代码原理解析

作者: 小疯子 分类: Shiro 发布时间: 2019-11-23 11:10
主要理一下用户登录认证的代码为啥那么写,更多关于shiro的入门学习就自己看有道云笔记中整理的大体内容

一、用户登录认证

1. 在loginController中调用
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
Subject subject = SecurityUtils.getSubject();
subject.login(token);实现登录
2. 编写继承于AuthenticatingRealm的realm类,并实现其中的抽象方法doGetAuthenticationInfo
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
// String username = (String) token.getPrincipal();
UserExt userExt = userService.getUserExtByUserName(usernamePasswordToken.getUsername());
if(userExt == null){
return null;
}
SimpleAuthenticationInfo authorizationInfo = new SimpleAuthenticationInfo(userExt.getUsername(), userExt.getPassword(), new Md5Hash(userExt.getSalt()), getName());
return authorizationInfo;
}
3. 以上二者的关系
subject.login(token)会将token传入 doGetAuthenticationInfo方法的参数中,二者是一致的。
可以通过token得到登录前端传入的username用户名;
4. 关于密码的比对
是通过CredentialsMatcher与SimpleAuthenticationInfo进行的。
CredentialsMatcher是针对用户输入的密码(loginController中)进行
前面UsernamePasswordToken存放的是登录输入的信息,而SimpleAuthenticationInfo则是存放了数据库中获取到的密码信息。
关于两者密码的比对,加断点查看执行记录会发现一个类AuthenticatingRealm的credentialsMatcher属性,通过这个属性继续找CredentialsMatcher类的doCredentialsMatch方法,有多个类对其实现,就是在这里进行的密码比对。
shiro01.png
通过token获取登录的密码信息,通过info获取SimpleAuthenticationInfo的密码信息,然后进行相等比较;具体怎么获取仍然可以查看源码;
5. 针对md5和salt加密的密码比对
(1)首先是对于登录密码的处理,需要使用CredentialsMatcher来进行md5或sha1进行处理,通过设置UserRealm的setCredentialsMatcher来设置HashedCredentialsMatcher对象
/**
* 设置密码加盐方式
*
* @param credentialsMatcher
*/
@Override
public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName(ShiroKit.HASH_ALGORITHM_NAME);
hashedCredentialsMatcher.setHashIterations(ShiroKit.HASH_ITERATIONS);
super.setCredentialsMatcher(hashedCredentialsMatcher);
}
shiro02.png
shiro03.png
(2)然后针对数据库对象密码和盐值设置如下所示
SimpleAuthenticationInfo authorizationInfo = new SimpleAuthenticationInfo(userExt.getUsername(), userExt.getPassword(), 盐值, getName());
SimpleAuthenticationInfo方法的第一个参数不需要必须是用户名,只是指定一个principal的名字而已,和密码比对没有关系
第二个参数对应于数据库的密码
第三个参数是盐值,作用于登录写入的密码,可以说是传入的那个token传入的密码是按照credentialsMatcher以及simpleAuthenticationInfo的加盐值进行计算的,计算出来之后再和数据库表中的credntical密码比对,查看HashedCredentialsMatcher的doCredentialsMatch如下所示
(3)比对代码如下,可见token的密码产生还传入了info,要的应该就是info的salt
shiro04.pngshiro05.png

将shiro集成到spring boot的代码见git: https://github.com/shuishuiafeng/feng-manage

0

发表评论

电子邮件地址不会被公开。 必填项已用*标注