shiro框架的密码校验(二)

其他的的内容在这里
shiro框架简单介绍以及使用(一)
shiro框架的权限设定(三)
shiro框架的密码校验进阶(四)多登陆方式实现思路
上一篇简单介绍了一下shiro框架和账号验证,这篇简单写一下shiro密码校验的介绍和几种使用方式

一、加密/加盐介绍

  • 什么是加密?什么是加盐?

    1.加密:加密是以某种特殊的算法改变原有的信息数据,这样的话即使你拿到了密文,但因为你不知道加密方式也没办法知道密文的内容。比如说电报,你监听到了发的电报,但是你不知道用的是那个密码本,一样无法知道电报内容是什么。
    2.加盐:加盐是指将每口令同一个叫做”盐“值相关联,我们这里用于密码加盐,盐值一般都是随机数。

  • 为什么要加密加盐?
    1.加密的作用我上面已经说了即使你拿到了密文,但因为你不知道加密方式也没办法知道密文的内容。
    2.加盐的话是为了让相同的密码值不同,例如说你使用的md5加密方式,只要你的密码是相同的,那么你加密后的数据也是相同的,这样如果密码密文泄露,只需要找到相应的加密方式就能还原明文密码,如果我们使用加盐加密,盐值为随机数,这样即使密码相同密文也会不同,加大安全性

二、实现加密的方式

2.1shiro提供的密码校验接口

Shiro 提供了 PasswordService 接口及 CredentialsMatcher 接口 用于密码的校验服务

CredentialsMatcher接口用于验证密码

在这里插入图片描述

boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info);

这个方法的token就是从前台过来的token,你在登录页面输入的明文账号密码

info的值是从重写AuthorizingRealm的doGetAuthenticationInfo(AuthenticationToken token)的返回值
也就是我上一篇写的AuthRealm中的doGetAuthenticationInfo方法的返回值

return new SimpleAuthenticationInfo(upToken.getUsername(), upToken.getPassword(), “ShiroReaml”);

通过重写CredentialsMatcher接口的doCredentialsMatch()方法然后将两个参数的值进行比对就可以做密码校验了

/***
     * @Description: 这块是登录验证配置
     * @Param: [token]
     * @return: org.apache.shiro.authc.AuthenticationInfo
     * @Author: lizelin
     * @Date: 2021/5/13 0013 1:25
    */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //AuthenticationToken转成UsernamePasswordToken这样可以直接拿到用户名和密码
        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
        String username = upToken.getUsername();
        //判断用户名是否为aaa否则抛出异常完事密码错误
        if(!username.equals("aaa")){
            throw new UnknownAccountException("用户错误");
        }
        return new SimpleAuthenticationInfo(upToken.getUsername(), upToken.getPassword(), "ShiroReaml");

PasswordService 用于加密密码
在这里插入图片描述
encryptPassword()方法为输入明文密码获得加密密文
passwordsMatch()方法为输入明文密码和输入加密密文进行比对

2.2shiro提供的密码校验实现

CredentialsMatcher提供的实现类:
  1. SimpleCredentialsMatcher
  2. HashedCredentialsMatcher
  3. PasswordMatcher

这三个实现类中HashedCredentialsMatcher为SimpleCredentialsMatcher的实现类。
但是SimpleCredentialsMatcher为明文密码校验,所以我们不做考虑。
后面主要讲HashedCredentialsMatcher与PasswordMatcher。
相对于PasswordMatcher来说HashedCredentialsMatcher的功能更加强大

三、shiro通过HashedCredentialsMatcher来实现密码校验

那么理论讲的差不多了,我们直接开始撸代码,没有代码的话去看我的上一篇文章,拿里面的代码进行修改

3.1将HashedCredentialsMatcher注入到securityManager中

我们需要将HashedCredentialsMatcher注入到AuthorizingRealm中才能使用
    //将自己的验证方式加入容器
    @Bean
    public Realm AuthRealm() {
        AuthRealm authRealm = new AuthRealm();
        HashedCredentialsMatcher credentials= new HashedCredentialsMatcher();
        credentials.setHashIterations(3);//加密次数
        credentials.setHashAlgorithmName("MD5");//加密方式
        authRealm.setCredentialsMatcher(credentials);//注入到AuthRealm实现类中
        return authRealm;
    }

将Shiro中的AuthRealm()方法修改注入HashedCredentialsMatcher实现类

3.2获得加密密文

这个因为我没连数据库,就模拟数据了,连接数据库也不难嗷,我把值都给你拿到,你放数据库就完事了
到时候用户注册或者是修改密码的时候,将明文密码放进来,获得密文与盐放入数据库
/***
 * @Description: 获得密文
 * @Param: 
 * @return: 
 * @Author: lizelin
 * @Date: 2021/5/14 0014 17:58
*/
@Component
public class CheckUtil{
    
    public String encryption(HashedCredentialsMatcher Hashed, char[] passWord){
        System.out.println("开始");
        String random = new SecureRandomNumberGenerator().nextBytes().toHex();//获得随机数盐值
        System.out.println(random);//打印盐值
        ByteSource salt=ByteSource.Util.bytes(random);//将盐值转为ByteSource类型
        System.out.println();
        //获得加密后的密码
        //SimpleHash hash = new SimpleHash("HashedCredentialsMatcher配置的加密方式","明文密码" , "盐值", "加密次数");
        SimpleHash hash = new SimpleHash(Hashed.getHashAlgorithmName(), passWord, salt, Hashed.getHashIterations());
        String encodedPassword = hash.toHex();
        //打印加密后的密文
        System.out.println(encodedPassword);
        return "";
    }

}

3.3跑起来获得盐和密文

首先打开我们的postman,然后访问

username为:aaa
password为:ccc

在这里插入图片描述
获得了盐值:6186808fa1ad5ba0ef39a88c97e900df
和加密密文:90a1626d55503a2c2e7eb345a4f3a607
然后我们去修改doCredentialsMatch()方法进行测试

3.4将盐值注入HashedCredentialsMatcher进行模拟测试

@Autowired
    CheckUtil check;
    /***
     * @Description: 这块是登录验证配置
     * @Param: [token]
     * @return: org.apache.shiro.authc.AuthenticationInfo
     * @Author: lizelin
     * @Date: 2021/5/13 0013 1:25
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //AuthenticationToken转成UsernamePasswordToken这样可以直接拿到用户名和密码
        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
        String username = upToken.getUsername();
        //判断用户名是否为aaa否则抛出异常完事密码错误
        if(!username.equals("aaa")){
            throw new UnknownAccountException("用户错误");
        }
        //这个3.3的测试写的,刚刚忘记写了
        check.encryption((HashedCredentialsMatcher)getCredentialsMatcher(),upToken.getPassword());
        //把盐放进来
        ByteSource salt=ByteSource.Util.bytes("6186808fa1ad5ba0ef39a88c97e900df");
        return new SimpleAuthenticationInfo(upToken.getUsername(), "90a1626d55503a2c2e7eb345a4f3a607", salt,getName());
        //new SimpleAuthenticationInfo(登录的用户名,数据库查的加密密码,盐值, Realm名可以直接写getName()随便叫啥没所谓)
    }

3.5测试密码加密以及校验是否正确

在这里插入图片描述
密码为ccc时登录成功,测试没毛病

在这里插入图片描述
密码为bbb时登录失败用户或密码不正确,测试没毛病

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值