欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-06-09 19:05:23
shiro简单的密码加盐与登录验证最近对后台管理框架非常的感兴趣,于是研究了通过什么进行了密码加盐加密的,并如何进行验证的,本次的所有讲解都是根据guns后端管理框架进行的个人理解一、pom.xml配置首先导入依赖,从guns项目的pom.xml中拽出并把版本号替换成1.3.2<!--shiro依赖和缓存--><dependency><groupId......

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简单的密码加盐与密码验证
到目前为止shiro简单的密码加盐与密码验证已经讲完了,小编有讲的不对的地方希望大家指出来,最后欢迎大家在博客下方评论交流。

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