当前位置: 移动技术网 > IT编程>开发语言>Java > shiro简单的密码加盐与密码验证

shiro简单的密码加盐与密码验证

2020年07月29日  | 移动技术网IT编程  | 我要评论

shiro简单的密码加盐与登录验证

最近对后台管理框架非常的感兴趣,于是研究了通过什么进行了密码加盐加密的,并如何进行验证的,本次的所有讲解都是根据guns后端管理框架进行的个人理解

一、pom.xml配置

首先导入依赖,从guns项目的pom.xml中拽出并把版本号替换成1.3.2

<!--shiro依赖和缓存-->
	<dependency>
		<groupId>org.apache.shiro</groupId>
		<artifactId>shiro-core</artifactId>
		<version>1.3.2</version>
		<exclusions>
			<exclusion>
				<artifactId>slf4j-api</artifactId>
				<groupId>org.slf4j</groupId>
			</exclusion>
		</exclusions>
	</dependency>
	<dependency>
		<groupId>org.apache.shiro</groupId>
		<artifactId>shiro-spring</artifactId>
		<version>1.3.2</version>
	</dependency>
	<dependency>
		<groupId>org.apache.shiro</groupId>
		<artifactId>shiro-ehcache</artifactId>
		<version>1.3.2</version>
		<exclusions>
			<exclusion>
				<artifactId>slf4j-api</artifactId>
				<groupId>org.slf4j</groupId>
			</exclusion>
		</exclusions>
	</dependency>
	<dependency>
		<groupId>org.ehcache</groupId>
		<artifactId>ehcache</artifactId>
	</dependency>
	<!--核心组件-->
	<dependency>
		<groupId>cn.stylefeng.roses</groupId>
		<artifactId>kernel-core</artifactId>
		<version>1.1.0</version>
	</dependency>

二、ShiroKit.java 导入工具类

/**
 * shiro工具类
 *
 * @author dafei, Chill Zhuang
 */
public class ShiroKit {

    private static final String NAMES_DELIMETER = ",";

    /**
     * 加盐参数
     */
    public final static String hashAlgorithmName = "MD5";

    /**
     * 循环次数
     */
    public final static int hashIterations = 1024;

    /**
     * shiro密码加密工具类
     *
     * @param credentials 密码
     * @param saltSource  密码盐
     * @return
     */
    public static String md5(String credentials, String saltSource) {
        ByteSource salt = new Md5Hash(saltSource);
        return new SimpleHash(hashAlgorithmName, credentials, salt, hashIterations).toString();
    }

    /**
     * 获取随机盐值
     *
     * @param length
     * @return
     */
    public static String getRandomSalt(int length) {
        return ToolUtil.getRandomString(length);
    }
}

三、创建实体类

此实体从guns中拽出来的,也可自行创建一个对应字段的实体


/**
 * 用户传输bean
 *
 * @author stylefeng
 * @Date 2017/5/5 22:40
 */
public class UserDto {

    private Integer id;
    private String account;
    private String password;
    private String salt;
    private String name;

    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date birthday;
    private Integer sex;
    private String email;
    private String phone;
    private String roleid;
    private Integer deptid;
    private Integer status;
    private Date createtime;
    private Integer version;
    private String avatar;


    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getSalt() {
        return salt;
    }

    public void setSalt(String salt) {
        this.salt = salt;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public Integer getSex() {
        return sex;
    }

    public void setSex(Integer sex) {
        this.sex = sex;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getRoleid() {
        return roleid;
    }

    public void setRoleid(String roleid) {
        this.roleid = roleid;
    }

    public Integer getDeptid() {
        return deptid;
    }

    public void setDeptid(Integer deptid) {
        this.deptid = deptid;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public Date getCreatetime() {
        return createtime;
    }

    public void setCreatetime(Date createtime) {
        this.createtime = createtime;
    }

    public Integer getVersion() {
        return version;
    }

    public void setVersion(Integer version) {
        this.version = version;
    }

    public String getAvatar() {
        return avatar;
    }

    public void setAvatar(String avatar) {
        this.avatar = avatar;
    }
}
import java.io.Serializable;
import java.util.List;

/**
 * 自定义Authentication对象,使得Subject除了携带用户的登录名外还可以携带更多信息
 *
 * @author fengshuonan
 * @date 2016年12月5日 上午10:26:43
 */
public class ShiroUser implements Serializable {

    private static final long serialVersionUID = 1L;

    public Integer id;          // 主键ID
    public String account;      // 账号
    public String name;         // 姓名
    public Integer deptId;      // 部门id
    public List<Integer> roleList; // 角色集
    public String deptName;        // 部门名称
    public List<String> roleNames; // 角色名称集


    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getDeptId() {
        return deptId;
    }

    public void setDeptId(Integer deptId) {
        this.deptId = deptId;
    }

    public List<Integer> getRoleList() {
        return roleList;
    }

    public void setRoleList(List<Integer> roleList) {
        this.roleList = roleList;
    }

    public String getDeptName() {
        return deptName;
    }

    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }

    public List<String> getRoleNames() {
        return roleNames;
    }

    public void setRoleNames(List<String> roleNames) {
        this.roleNames = roleNames;
    }

}

四、创建测试用例test.java

代码比较多,一步一步在代码中讲解

public class test {
    public static void main(String[] args){
                                      //假设向数据库存入加密的对象
        UserDto user=new UserDto();   //创建一个对象
        user.setPassword("123456");   //模拟密码123456
        user.setSalt(ShiroKit.getRandomSalt(5));   //获取5位数的盐
        user.setPassword(ShiroKit.md5(user.getPassword(), user.getSalt()));   //把盐与密码传入方法中进行 md5加密方式 的1024次加密  最后得出加密密码
        System.out.println("密码:"+user.getPassword()+"     "+"Salt:"+ user.getSalt());  //打印  加密后的密码   与   盐的值
//最后把对象存入数据库中,小编看的guns项目以用户名不重复才可存入数据库

//模拟密码
        String str=new String();
        str="123456";   //模拟密码为123456
        //封装请求账号密码为shiro可验证的token
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken("huasheng", str.toCharArray());   //"huasheng"为登录时输入的用户名,这里直接写了字符串

        //获取数据库中的账号密码,准备比对   查找用户名所在的用户数据  这里直接用上面定义的user进行测试
//        User user = userMapper.getByAccount(username);

        String credentials = user.getPassword();//获取本账号加密过的密码
        String salt = user.getSalt();           //获取本账号中对应盐值
        ByteSource credentialsSalt = new Md5Hash(salt); //放入盐值
        System.out.println("credentialsSaltgetBytes"+credentialsSalt.getBytes());
        System.out.println("credentialsSaltgetClass"+credentialsSalt.getClass());
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
                new ShiroUser(), credentials, credentialsSalt, "");//第一个参数是对象,密码,ByteSource对象,realmName

        //校验用户账号密码
        HashedCredentialsMatcher md5CredentialsMatcher = new HashedCredentialsMatcher();
        md5CredentialsMatcher.setHashAlgorithmName(ShiroKit.hashAlgorithmName);//MD5
        md5CredentialsMatcher.setHashIterations(ShiroKit.hashIterations);//1024
        boolean passwordTrueFlag = md5CredentialsMatcher.doCredentialsMatch( usernamePasswordToken, simpleAuthenticationInfo);//验证

        if (passwordTrueFlag) {
//            HashMap<String, Object> result = new HashMap<>();
//            result.put("token", JwtTokenUtil.generateToken(String.valueOf(user.getId())));
//            return result;
            System.out.println("登陆成功");
        } else {
//            return new ErrorResponseData(500, "账号密码错误!");
            System.out.println("账号密码错误!");
        }
    }
}

运行结果:
在这里插入图片描述
到目前为止shiro简单的密码加盐与密码验证已经讲完了,小编有讲的不对的地方希望大家指出来,最后欢迎大家在博客下方评论交流。

本文地址:https://blog.csdn.net/qq1026432050/article/details/85944252

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网