码迷,mamicode.com
首页 > 其他好文 > 详细

Shiro___加密加盐迭代

时间:2019-06-06 09:21:38      阅读:208      评论:0      收藏:0      [点我收藏+]

标签:mep   real   rgs   equal   exception   spring   miss   catch   ext   

简单的模拟账号密码登入,为了简便就不去数据库真实的查询了

这里先使用MD5加盐迭代加密,算出我们的密码加密结果
MD5是不可逆的,单向加密,所以我们需要对原始数据进行加密后与加密的数据对比,而不是去解密

package com.test;

import org.apache.shiro.crypto.hash.Md5Hash;
/**
 * 对123456加密,
 * 盐值(salt):zsl
 * 迭代次数:6
 * 加密结果:70fc2a964652cf72d7f67022a7951e51
 * @author Administrator
 *
 */
public class MD5Test {

    public static void main(String[] args) {
        Md5Hash mdh = new Md5Hash("123456", "zsl", 6);
        System.out.println(mdh);
        //70fc2a964652cf72d7f67022a7951e51
    }
}

自定义的Realm:
认证方法

package com.test;

import java.util.ArrayList;
import java.util.List;

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.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.SimpleByteSource;

public class MyRealm extends AuthorizingRealm{

    /**
     * 授权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        // 获取当前登录的账号
        Object principal = principals.getPrimaryPrincipal();
        
        List<String> roleList = new ArrayList<>();
        List<String> psList = new ArrayList<>();
        roleList.add("role1");
        roleList.add("role2");
        roleList.add("role3");
        
        psList.add("create");
        psList.add("query");
        psList.add("delete");
        
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        
        info.addRoles(roleList);
        info.addStringPermissions(psList);
        
        return info;
    }

    /**
     * 认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {
        // TODO Auto-generated method stub
        //获取账号信息
        Object principal = arg0.getPrincipal();
        //从数据库等数据源获取数据
        String name = "root";
        
        if (!name.equals(principal)) {//低质量的匹配认证
            return null;
        }
        //根据账号去数据库查询出密码
        //经过加密加盐迭代后的密码,这里模拟从数据库查询出了已加密的结果
        String pwd = "70fc2a964652cf72d7f67022a7951e51";
        
        //我们知道自定义的Realm是不验证密码的,实际验证密码的是AuthenticatingRealm中的AuthenticationInfo方法
        //这里的SimpleAuthenticationInfo就是封装好的验证密码的方法
        //这里提供了new SimpleByteSource("zsl"),zsl是盐值,而迭代次数在ini中
        AuthenticationInfo  info = new SimpleAuthenticationInfo(principal,pwd,new SimpleByteSource("zsl"),  "MyRealm");
        
        return info;
    }

}

在没有整合其他框架,如Spring前,我们这里配置ini文件来代替xml以及数据库
Shiro.ini:

[main] #定义凭证匹配器 credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher #散列算法 credentialsMatcher.hashAlgorithmName=md5 #散列次数 credentialsMatcher.hashIterations=1 #将凭证匹配器设置到realm customRealm=com.dpb.realm.MyRealm customRealm.credentialsMatcher=$credentialsMatcher securityManager.realms=$customRealm

测试:

public class Test {
    public static void main(String[] args) {
        // 获取SecurityManagerFactory对象
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        // 根据工厂对象获取SecurityManager对象
        SecurityManager manager = factory.getInstance();
        // 将SecurityManager添加到运行环境中
        SecurityUtils.setSecurityManager(manager);
        
        // 获取Subject对象
        Subject subject = SecurityUtils.getSubject();   
        // 获取对应的认证令牌
        AuthenticationToken token = new UsernamePasswordToken("root", "123456") ;
        // 做登录认证
        try {
            subject.login(token);
            System.out.println("登录成功....");
        } catch (UnknownAccountException e) {
            System.out.println("账号错误...");
        } catch (IncorrectCredentialsException e) {
            System.out.println("密码错误...");
        }
        System.out.println(subject.isAuthenticated());
}
}

这里是类似于把密码加密加盐迭代后的结果存到数据库,然后客户端请求来的密码是没有加密加盐迭代的,我们需要对它也同样的进行加密加盐迭代,与通过账号到数据库查询出来的密码进行比对。我们知道自定义的Realm是不验证密码的,实际验证密码的是AuthenticatingRealm中的AuthenticationInfo方法去验证密码,所以我们这里自定义的Realm继承AuthorizingRealm重写了doGetAuthenticationInfo方法,这样我们就可以对我们的账号和密码进行相关业务操作。

Shiro___加密加盐迭代

标签:mep   real   rgs   equal   exception   spring   miss   catch   ext   

原文地址:https://www.cnblogs.com/zhangsonglin/p/10983071.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!