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简单的密码加盐与密码验证已经讲完了,小编有讲的不对的地方希望大家指出来,最后欢迎大家在博客下方评论交流。
本文地址:https://blog.csdn.net/qq1026432050/article/details/85944252