Shiro--密码加密

散列算法

散列算法一般用于生成一段文本的摘要信息,将内容可以生成摘要,无法将摘要转成原始内容。

  • 散列算法不可逆
  • 散列算法常用于对密码进行散列
  • 常用的散列算法有 MD5、SHA

一般散列算法需要提供一个 salt (盐) 与原始内容生成摘要信息,这样做的目的是为了安全性

比如:111111 的 md5值是:96e79218965eb72c92a549dd5a330112,
拿着 96e79218965eb72c92a549dd5a330112 去md5破解网站很容易进行破解

如果要是对111111和salt(盐,一个随机数)进行散列,这样虽然密码都是111111,但是 加不同的盐会生成不同的散列值

@Test
public void test() { //md5加密,不加盐
	String password_md5 = new Md5Hash("111111").toString(); 			
	System.out.println("password_md5=" + password_md5);
	//md5加密,加盐 一次散列
	String password_md5_salt_1 = new Md5Hash("111111", "imcode", 1).toString(); 
	System.out.println("password_md5_salt_1=" + password_md5_salt_1);
	//两次散列相当于md5(md5())
	String password_md5_salt_2 = new Md5Hash("111111", "imcode", 2).toString(); 
	System.out.println("password_md5_salt_2=" + password_md5_salt_2);
	//使用SimpleHash
	String password_md5_simpleHash = new SimpleHash("MD5", "111111", "imcode", 2).toString();
	System.out.println("password_md5_simpleHash=" + password_md5_simpleHash); 
}

加密工具类

public class MD5Util {
    // 散列次数
    private static int hashIterations = 3;

    private static String salt = "ak47";
    /**
     * md5加密工具类
     * @param source
     * @param salt
     * @return
     */
    public static String md5(String source, String salt) {
        return new Md5Hash(source, salt, hashIterations).toString();
    }

    public static String md5_salt(String source) {
        return new Md5Hash(source, salt, hashIterations).toString();
    }
}

Realm

public class ShiroRealm extends AuthorizingRealm {


    /**
     * 登录认证
     *
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;

        // 1.获取用户输入的用户名
        String username = token.getUsername();
        // 2.获取用户输入的密码
        String password = new String(token.getPassword());

        // 3.根据用户名去DB查询对应的用户信息,密码为加密后的密文
        User user = new User("admin", "3635b070bdf50a94f350c1d050ab1b61", 0);
        //User user = new User("admin", "123456", 0);
        if (!user.getUsername().equals(username)) {
            throw new UnknownAccountException("用户名不存在");
        }
        if (!user.getPassword().equals(password)) {
            throw new CredentialsException("密码错误");
        }
        if (user.getStatus() == 1) {
            throw new DisabledAccountException("账号被禁用");
        }
        if (user.getStatus() == 2) {
            throw new LockedAccountException("账号被锁定");
        }

        System.out.println("认证成功...");

        // 创建简单认证信息对象
        SimpleAuthenticationInfo info =
                new SimpleAuthenticationInfo(token.getPrincipal(), token.getCredentials(), getName());

        return info;
    }


    /**
     * 授权
     * 将认证通过的用户的角色和权限信息设置到对应用户主体上
     *
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        String username = principals.getPrimaryPrincipal().toString();


        //模拟从数据库获取当前用户的角色 通过用户名查询该用户拥有的角色名称
        Set<String> roleNameSet = new HashSet<>();
        roleNameSet.add("系统管理员");
        //roleNameSet.add("系统运维");

        //模拟从数据库获取当前用户的权限 通过用户名查询该用户拥有的权限名称
        Set<String> permissionNameSet = new HashSet<>();
        permissionNameSet.add("sys:user:list"); // 查看列表
        permissionNameSet.add("sys:user:info"); // 查看用户详情
        permissionNameSet.add("sys:user:create");// 创建用户
        permissionNameSet.add("sys:user:update");// 修改用户
        permissionNameSet.add("sys:user:delete");// 删除用户

        // 简单授权信息对象,对象中包含用户的角色和权限信息
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addRoles(roleNameSet);
        info.addStringPermissions(permissionNameSet);

        System.out.println("授权完成....");
        return info;
    }


}

测试:

@Test
    public void test04() {
        // 模拟从客户端接收到用户登录输入的用户名和密码(明文)
        String username = "admin";
        String password = "123456";


        // 将明文的密码加密成密文
        String salt = MD5Util.md5_salt(username + password);
        password = MD5Util.md5(password, salt);

        // 登录认证
        ShiroUtil.login(username, password);
    }

控制台打印:

认证成功...
[DEBUG] Looked up AuthenticationInfo [admin] from doGetAuthenticationInfo 
[DEBUG] AuthenticationInfo caching is disabled for info [admin].  Submitted token: [org.apache.shiro.authc.UsernamePasswordToken - admin, rememberMe=false]. 
[DEBUG] Performing credentials equality check for tokenCredentials of type [[C and accountCredentials of type [[C] 
[DEBUG] Both credentials arguments can be easily converted to byte arrays.  Performing array equals comparison 
[DEBUG] Authentication successful for token [org.apache.shiro.authc.UsernamePasswordToken - admin, rememberMe=false].  Returned account [admin] 
[DEBUG] No sessionValidationScheduler set.  Attempting to create default instance. 
[INFO] Enabling session validation scheduler... 
[DEBUG] Creating new EIS record for new session instance [org.apache.shiro.session.mgt.SimpleSession,id=null] 
发布了716 篇原创文章 · 获赞 2079 · 访问量 26万+

猜你喜欢

转载自blog.csdn.net/cold___play/article/details/104235486