shiro搭配MD5的加密认证思路,以小案例讲解

本篇案例是由IDEA创建的maven的java项目



步骤一:在pom.xml导入如下依赖

   <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-all</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
   </dependency>


步骤二:在java文件夹下创建我们自定义的Realm,此案例我自定义的Realm名叫MyRealm2。代码如下

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;


//加密认证
//自定义Realm
//shiro框架都是基于Realm来实现的,也就是我们自定义的这个
public class MyRealm2 extends AuthorizingRealm{//自定义Realm操作数据库,必须继承AuthorizingRealm
    //za这个方法用于授权的
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }
//ic这个方法时用于认证的
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //先得到Demo3中提交的用户名
        String username = (String)authenticationToken.getPrincipal();
        //判断正确的用户名
        //假设正确的用户名为admin,密码为123(密码在MD5中加密后为a906449d5769fa7361d7ecc6aa3f6d28)
        String truePassword="f30aa7a662c728b7407c54ae6bfd27d1";//在Testmd5中123加密后的密码
        String salt="hello";//在Testmd5中加密用的盐值

        if(username.equals("admin")){// 此处我们只判断用户名是否正确,密码验证让shiro框架完成。admin是我们数据库中存储的用户名即shiro.ini,在这个小案例中shiro.ini是充当数据库的作用,shiro.ini文件shiro底层会根据文件标签自动读取。到后期用ssm调用dao层方法,获取mapper中的sql语句查询的数据信息可代替admin那个位置,从而相当于替代了shiro.ini文件,因为我们不用再写数据到shiro.ini文件中
             return new SimpleAuthenticationInfo(username,truePassword,ByteSource.Util.bytes(salt),"myrealm");//ByteSource.Util.bytes(salt)固定用法//realmName是指当前工具类的名称,该名称是自定义的。即myrealm这个名字是自定义的.
        }
        return null;
    }
}



步骤三:在resources下创建指定我们自定义Realm即MyRealm2的.ini文件,用于告诉shiro去执行哪个Realm,执行默认的还是我们定义的?如果没自定义会有一个默认的。

此案例我们将指定我们定义的MyRealm2的.ini文件命名为shiro-myrealmmd5.ini,代码如下:

[main]
#定义凭证匹配器,org.apache.shiro.authc.credential.HashedCredentialsMatcher是固定的完整路径
matcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher


#散列算法,散列算法有两种,即MD5和SHA,因为MyRealm2即我们自定义的Realm文件是MD5加密的,因此这里也指定MD5进行解密
matcher.hashAlgorithmName=md5


#散列次数
matcher.hashIterations=1



#将凭证匹配器设置到realm。第一个等式解释:左侧的myRealm是自定义的,可随便写,但要与下面对应位置(即myRealm.credentialsMatcher和$myRealm)的名字相同,右侧的test4.MyRealm2是我们自定义的Realm路径(包路径加类名),告诉shiro用哪一个Realm;第二个等式解释:左侧myRealm.credentialsMatcher的credentialsMatcher是固定搭配,右侧的$matcher是上面的凭证器的名称。第三个等式:左侧securityManager.realms指定任务类,固定搭配?右侧$myRealm即上面的凭证器
myRealm=test4.MyRealm2
myRealm.credentialsMatcher=$matcher
securityManager.realms=$myRealm

注意:ini文件中[main]、[users]、[roles]这几个打头的标签,其次ini中的#是注释说明的作用



步骤四:上面相当于在搭建shiro的执行环境,接下来我们就可以开始在java文件夹下创建我们我执行类来测试效果了。我将该类定义为Demo3,代码如下:

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;

public class Demo3 {
    public static void main(String[] args) {
        //创建安全管理对象
        Factory<SecurityManager> factory=
                new IniSecurityManagerFactory("classpath:shiro-myrealmmd5.ini");//注意着个泛型导的包,由于自动导的是java.lang包,所以手动导的。其次shiro-myrealmmd5.ini是指定我们自定义的Realm即MyRealm2的路径,可能因为在同一项目下,相对路径问题,读取的原因,直接在此处写一个名字即可。另外,classpath:这是固定的,不能少了。
        //创建具体对象
        SecurityManager instance=(SecurityManager) factory.getInstance();
        //添加安全管理器对象导工具类中
        SecurityUtils.setSecurityManager(instance);
        //创建主体信息
        Subject subject=SecurityUtils.getSubject();
        //创建UsernamePasswordToken 对象保存用户登录时的用户名和密码。--------------灵活步骤
        UsernamePasswordToken token=
                new UsernamePasswordToken("admin","123");//用户登录后我们将其存在UsernamePasswordToken中,用于subject.isAuthenticated()判断存的这个是否和shiro.ini文件中的一致。shiro.ini在本例子中相当于数据库的角色,因为真正的用户名和密码肯定是存在数据库中
        //认证
      subject.login(token);  //提交认证,利用login方法将用户写的用户名和密码提交给我们自定义的Realm即MyRealm2中的认证部分进行认证,下面的isAuthenticated()方法则是认证后返回的结果,该返回结果只有true和false

        //测试认证结果(subject.isAuthenticated()用于判断主体信息即用户名和密码是否正确)
      /*此行代码是比对效果*/  boolean b = subject.isAuthenticated();//isAuthenticated用于比对UsernamePasswordToken 中存的是否存在于shiro.ini中,若在则返回true。不存在shiro.ini中则返回false
        System.out.println("认证结果一:"+b);
        //退出
        subject.logout();
        boolean b2=subject.isAuthenticated();
        System.out.println("认证结果2:"+b2);
     }


}





此案例的在我的IDEA中的框架图:
在这里插入图片描述
此案例执行结果:
在这里插入图片描述








上面的案例就结束了。下面这个代码是上面用到的MD5加密的那个字符串。就是用如下代码查到的。该类直接创建在java文件夹下即可,本处吧该类命名为Testmd5

import org.apache.shiro.crypto.hash.Md5Hash;
//此类只是用于让我们看到123在MD5中加密后的结果
public class Testmd5 {
    public static void main(String[] args) {
        Md5Hash hash= new Md5Hash("123","hello",1);//123是我们要用MD5加密的密码;hello是盐值,即在加密前先在密码后面追加上hello;1那位置代表加密几次,此处加密一次。此处除了密码相对固定外,其他两个都可随便定义
        System.out.println(hash.toString());
    }

}

Testmd5运行结果:
在这里插入图片描述
这个结果其实就是我们自定义Realm文件即MyRealm2中的密码,
String truePassword=“f30aa7a662c728b7407c54ae6bfd27d1”;
也是我们为了提高安全性,在数据库中存的真正的用户密码







总结:我们为了自由读取数据库信息,我们自定义了Realm即案例中的MyRealm2类;该类通过我们自定义的shiro-myrealmmd5.ini来告诉shiro框架加载哪个Realm,用哪种方式来加载;在执行类中我们通过new IniSecurityManagerFactory(ini文件路径)来读取shiro-myrealmmd5.ini文件,并找到要执行的Realm。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值