shiro:加密及密码比对器(三)
基于【自定义remle(二)】项目增加加密功能
1:数据库t_user表增加一列(盐)
增加字段:salt
CREATE TABLE `t_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(20) NOT NULL,
`password` varchar(100) NOT NULL,
`salt` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
2:javaBean增加一个属性(盐)
com\shiro\vo\UserVo.java
//加密 盐
private String salt;
3:mapper层增加添加用户方法
com\shiro\mapper\UserMapper.java
//注册用户
public void addUser(UserVo userVo);
4:mapper.xml层增加添加用户方法
com\shiro\mapper\UserMapper.xml
<insert id="addUser" parameterType="UserVo">
insert into t_user(username, password,salt) values (#{username},#{password},#{salt})
</insert>
5:service接口增加添加用户的方法以及实现
com\shiro\service\UserService.java
/*注册用户*/
public void addUser(UserVo userVo);
com\shiro\service\impl\UserServiceImpl.java
public void addUser(UserVo userVo) {
//加密 盐 随机数
String salt = UUID.randomUUID().toString();
//Sha类型加密 密码 盐 10000次迭代
String s = new Sha256Hash(userVo.getPassword(), salt, 10000).toBase64();
//数据库中存放加密的密码
userVo.setPassword(s);
//数据库中存放加密盐
userVo.setSalt(salt);
this.userMapper.addUser(userVo);
}
6:controller层新增注册用户的方法
com\shiro\controller\LoginController.java
/*跳转用户注册页*/
@GetMapping("/regist")
public String goRegist(UserVo userVo){
return "regist";
}
/*注册用户*/
@PostMapping("/regist")
public String regist(UserVo userVo){
userService.addUser(userVo);
return "login"; //注册成功后跳转登录页面
}
7:构建注册页面
WEB-INF\jsp\regist.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<html>
<head>
<title>Title</title>
</head>
<body>
请注册:
<form action="/user/regist" method="post">
username:<input type="text" name="username"><br />
password:<input type="text" name="password"><br />
<button type="submit">注册</button>
</form>
</body>
</html>
8:用户注册
数据库添加成功:
9:登录改造
1》在shiro.ini中添加密码比对器
resources\shiro.ini
[main]
........略.......
#声明密码比对器(+)
credentialsMatcher = org.apache.shiro.authc.credential.HashedCredentialsMatcher
#加密类型(+)
credentialsMatcher.hashAlgorithmName = sha-256
#加密迭代次数(+)
credentialsMatcher.hashIterations = 10000
#true=hex格式 false=base64(+)
credentialsMatcher.storedCredentialsHexEncoded = false
#声明自定义realm
realm = com.shiro.realm.MyRealm
#注册密码比对器(+)
realm.credentialsMatcher = $credentialsMatcher
#注册安装自定义realm
securityManager.realms=$realm
[urls]
........略.......
2》修改自定义realm
com\shiro\realm\MyRealm.java
把返回的SimpleAuthenticationInfo做修改,增加一个参数(盐),realm自动比对
/*查询身份信息
* 触发:subject.login(token)
* */
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//获取用户登录时发送过来的用户名
String username = token.getPrincipal().toString();
//查询用户信息(DB)
UserService userServiceImpl = ContextLoader.getCurrentWebApplicationContext().getBean("userServiceImpl", UserService.class);
UserVo userVo = userServiceImpl.queryUserByUsername(username);
if(userVo==null){
return null;
}
/*多了一个参数(盐):ByteSource.Util.bytes(userVo.getSalt())*/
return new SimpleAuthenticationInfo(userVo.getUsername(),
userVo.getPassword(),
ByteSource.Util.bytes(userVo.getSalt()), //盐
this.getName());
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用