shiro自定义realm支持MD5算法认证(六)

1.1     散列算法

通常需要对密码 进行散列,常用的有md5、sha,

 

对md5密码,如果知道散列后的值可以通过穷举算法,得到md5密码对应的明文。

建议对md5进行散列时加salt(盐),进行加密相当 于对原始密码+盐进行散列。(盐就相当于加入一个随机数)

正常使用时散列方法:

在程序中对原始密码+盐进行散列,将散列值存储到数据库中,并且还要将盐也要存储在数据库中。

 

如果进行密码对比时,使用相同 方法,将原始密码+盐进行散列,进行比对。

 

1.2 MD5测试

 

复制代码
package cn.qlq.authentication;


import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.crypto.hash.SimpleHash;

/**
 * 测试MD5算法
* @author: qlq
* @date :  2017年7月28日下午9:31:45
 */
public class MD5Test {
    
    public static void main(String[] args) {
        
        //原始 密码 
        String source = "111111";
        //
        String salt = "qwerty";
        //散列次数
        int hashIterations = 2;
        //上边散列1次:f3694f162729b7d0254c6e40260bf15c
        //上边散列2次:36f2dfa24d0a9fa97276abbe13e596fc
        
        
        //构造方法中:
        //第一个参数:明文,原始密码 
        //第二个参数:盐,通过使用随机数
        //第三个参数:散列的次数,比如散列两次,相当 于md5(md5(''))
        Md5Hash md5Hash = new Md5Hash(source, salt, hashIterations);
        String password_md5 =  md5Hash.toString();
        System.out.println(password_md5);
        
        
//        第二种方法
        //第一个参数:散列算法 
        SimpleHash simpleHash = new SimpleHash("md5", source, salt, hashIterations);
        System.out.println(simpleHash.toString());
        
        
        
    }

}
复制代码

 

 

---------------------------------------------------------------------------------------   自定义realm支持散列算法------------------------------------------------------------------------------------------------------------------

     新建realm(CustomRealmMd5)   如果未采用md5算法则不用红色部分第三个参数:

复制代码
package cn.qlq.realm;

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实现MD5散列算法加密
* @author: qlq
* @date :  2017年7月28日下午9:33:14
 */
public class CustomRealmMd5 extends AuthorizingRealm {

    // 设置realm的名称
    @Override
    public void setName(String name) {
        super.setName("customRealmMd5");
    }

    // 用于认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(
            AuthenticationToken token) throws AuthenticationException {

        // token是用户输入的
        // 第一步从token中取出身份信息
        String userCode = (String) token.getPrincipal();

        // 第二步:根据用户输入的userCode从数据库查询
        // ....

        // 如果查询不到返回null
        // 数据库中用户账号是zhangsansan
        /*
         * if(!userCode.equals("zhangsansan")){// return null; }
         */

        // 模拟从数据库查询到密码,散列值
        String password = "f3694f162729b7d0254c6e40260bf15c";
        // 从数据库获取salt
        String salt = "qwerty";
        //上边散列值和盐对应的明文:111111

        // 如果查询到返回认证信息AuthenticationInfo
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
                userCode, password, ByteSource.Util.bytes(salt), this.getName());

        return simpleAuthenticationInfo;
    }

    // 用于授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(
            PrincipalCollection principals) {
        // TODO Auto-generated method stub
        return null;
    }

}
复制代码

 

 

 

         realm中配置凭证匹配器

 

 

测试:

复制代码
// 自定义realm实现散列值匹配
        @Test
        public void testCustomRealmMd5() {

            // 创建securityManager工厂,通过ini配置文件创建securityManager工厂
            Factory<SecurityManager> factory = new IniSecurityManagerFactory(
                    "classpath:shiro-realm-md5.ini");

            // 创建SecurityManager
            SecurityManager securityManager = factory.getInstance();

            // 将securityManager设置当前的运行环境中
            SecurityUtils.setSecurityManager(securityManager);

            // 从SecurityUtils里边创建一个subject
            Subject subject = SecurityUtils.getSubject();

            // 在认证提交前准备token(令牌)
            // 这里的账号和密码 将来是由用户输入进去
            UsernamePasswordToken token = new UsernamePasswordToken("zhangsan",
                    "111111");

            try {
                // 执行认证提交
                subject.login(token);
            } catch (AuthenticationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            // 是否认证通过
            boolean isAuthenticated = subject.isAuthenticated();

            System.out.println("是否认证通过:" + isAuthenticated);

        }
        
复制代码

 

 

posted @   QiaoZhi  阅读(1545)  评论(0编辑  收藏  举报
编辑推荐:
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示