Shiro 自定义密码验证类

上篇 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 ~

猜你喜欢

转载自blog.csdn.net/qq_42402854/article/details/89441459