上篇 Shiro 重放攻击登录验证 进行表单登录验证
其中,我们可以把在 LoginController 中密码验证的功能提取出来,我们自定义一个密码验证类进行验证,这样可以使我们处理更复杂情况的验证工作。
步骤:1、将 LoginController 中表单密码验证提取出来,在自定义密码验证类实现
1)注释其验证工作
@PostMapping("/login")
public String login(User user, HttpSession session) {
//使用 shiro 登录验证
//1 认证的核心组件:获取 Subject 对象
Subject subject = SecurityUtils.getSubject();
/*//将密码进行 aes 解密
String key = (String) session.getAttribute("uuidSalt");
String iv = (String) session.getAttribute("uuidSalt");
try {
user.setPazzword(AesEncryptUtil.desEncrypt(user.getPazzword(), key, iv));
//密码解码成功后盐值失效
session.removeAttribute("uuidSalt");
} catch (Exception e1) {
e1.printStackTrace();
return "loginError";
}*/
//2 将登陆表单封装成 token 对象
UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPazzword());
try {
//3 让 shiro 框架进行登录验证:
subject.login(token);
} catch (Exception e) {
e.printStackTrace();
return "loginError";
}
return "redirect:/admin/index";
}
2)自定义密码验证类: extends SimpleCredentialsMatcher
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.session.Session;
import cn.jq.ssm.utils.AesEncryptUtil;
public class MyCredentialsMatcher extends SimpleCredentialsMatcher{
@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
// 完全由自己定义用户输入的密码,和数据库中的密码的对比规则
UsernamePasswordToken token2 = (UsernamePasswordToken) token;
String pazzword = new String(token2.getPassword());
//从服务器中取出uuidSalt(org.apache.shiro.session.Session)
Session session = SecurityUtils.getSubject().getSession();
//将密码进行 aes 解密
String key = (String) session.getAttribute("uuidSalt");
String iv = (String) session.getAttribute("uuidSalt");
try {
pazzword = AesEncryptUtil.desEncrypt(pazzword, key, iv);
//密码解码成功后盐值失效
session.removeAttribute("uuidSalt");
} catch (Exception e) {
e.printStackTrace();
throw new IncorrectCredentialsException("受到重放攻击!");
}
String formpPzzword = new SimpleHash("MD5", pazzword, "JQSalt", 1024).toString();
String accountCredentials = String.valueOf(getCredentials(info));
return formpPzzword.equals(accountCredentials);
}
重写 doCredentialsMatch 方法: SimpleCredentialsMatcher 使用Object类型,我们使用 String 相等比较(Object没成功,当时值正确,然而ByteSource不正确,待学习),
2、 运行项目访问登录即可
end ~