shiro 密码(凭证)比较器问题
问题背景
这是在修改shiro项目的登录密码处理时遇到的一个问题,是sso单点登录的逻辑要通过shiro进行登录验证。但是问题是我从单点登录入口拿到的信息没有密码,数据库中存储的是MD5摘要出来的密文,无法通过正常手段获得明文密码。
异常原因
单点登陆业务逻辑进行shiro验证的时候,无法获取明文密码,无法通过shiro的默认凭证比较器的验证。
org.apache.shiro.authc.IncorrectCredentialsException: did not match the expected credentials.
如何解决
通过继承SimpleCredentialsMatcher 自定义一个密码比较器,重写逻辑
/**
* @Date: 2020/3/30 20:46
* @Description:
* shiro
* 自定义密码比较器
*/
public class CredentialMatcher extends SimpleCredentialsMatcher {
@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
UsernamePasswordToken uToken = (UsernamePasswordToken)token;
//前台传入的密码
String password = new String(uToken.getPassword());
//获取数据库存放的的密码
String dbPassword = (String) info.getCredentials();
if(dbPassword.equals(password.trim())){
//单点登录情况,传入的是从后台获取的md5值
return true;
}else {
//正常登录的情况,传入的是密码值,md5
String pwd = MD5.encodeByMD5(password.trim());
if(dbPassword.equalsIgnoreCase(pwd)){
return true;
}else {
return this.equals(pwd, dbPassword);
}
}
}
}
ShiroConfig配置修改
@Configuration
public class ShiroConfig {
@Bean(name = "loginRealm")
public UserRealm getLoginRealm(){
UserRealm realm= new UserRealm();
//通过自定义CredentialMatcher,重新实现doCredentialsMatch方法加入sso的特殊比较规则。
realm.setCredentialsMatcher(credentialMatcher());
// realm.setCredentialsMatcher(getHashedCredentialsMatcher());
return realm;
}
@Bean
public CredentialMatcher credentialMatcher() {
//自定义的密码比较器
return new CredentialMatcher();
}
@Bean
public HashedCredentialsMatcher getHashedCredentialsMatcher(){
//原有默认的不再使用
HashedCredentialsMatcher rm = new HashedCredentialsMatcher();
rm.setHashAlgorithmName("md5");
rm.setHashIterations(1);
return rm;
}
}
天下英雄出我辈,一入江湖岁月催
我是爱生活的「无间行者」,努力把实践过的解决方案分享给大家
如果这篇文章对你有用,一个赞、一个评论、一个关注,我都很开心,给点鼓励吧,让我知道你在看。