接之前的案例 在shiroConfig添加几个配置
1.加密配置
/**
* 创建自定义配置的Realm
*/
@Bean
CustomRealm myRealm() {
CustomRealm customRealm = new CustomRealm ( );
//注入加密算法
customRealm.setCredentialsMatcher (hashedCredentialsMatcher ());
return customRealm;
}
/**
* 密码加密算法设置
* @return
*/
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher(){
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
//加密方式
hashedCredentialsMatcher.setHashAlgorithmName("md5");
//散列的次数
hashedCredentialsMatcher.setHashIterations(2);
return hashedCredentialsMatcher;
}
2.这个工具是添加用户时使用,把作用是MD5加密
public class PasswordGenerateUtil {
/**
* username 用户名
* password 密码
* salt 未加工的盐
* hashTimes 散列次数2
* */
public static String getPassword(String username,String password,String salt,int hashTimes){
//真盐 == username+salt
Md5Hash md5Hash = new Md5Hash(password,username+salt,hashTimes);
return md5Hash.toString();
}
}
3.修改dao 和接口映射x’m’l
//根据用户名查密码 和盐 id
@Select ("SELECT * FROM USER WHERE NAME =#{name}")
User getPwdByName(String name);
//插入一个用户
Integer insert(User user);
插入用户sql
<insert id="insert" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
INSERT INTO USER(NAME,PASSWORD,salt)VALUES(#{name},#{password},#{salt})
</insert>
4.创建用户的业务还需要给他设置角色,所以需要一个RoleDao以及mapper.xml
@Mapper
@Repository
public interface RoleDao {
//创建用户时 关联角色和用户就可以了
//因为角色和权限直接关联
//一般创建一个用户不需要设置权限表
Integer insert(@Param ("array") Integer[] array,@Param ("uid") Integer uid);
}
不确定一个还是多个角色,所以使用foreach批量插入:
<mapper namespace="com.shiro.dao.RoleDao">
<insert id="insert">
insert into user_role(uid, rid) values
<foreach collection="array" separator="," item="rid">
(#{uid},#{rid})
</foreach>
</insert>
</mapper>
UserServiceImpl业务层 添加用户 需要对密码加密,加密后插入数据库
import java.util.List;
@Service
@Transactional(rollbackFor = Exception.class)
public class UserServiceImpl implements UserService {
@Autowired
UserDao userDao;
@Override
public User getPwdByName(String name) {
return userDao.getPwdByName (name);
}
@Override
public List<String> listRoles(String name) {
return userDao.listRoles (name);
}
@Override
public List<String> listPermissions(String name) {
return userDao.listPermissions (name);
}
@Override
public Integer insert(User user) {
User name = userDao.getPwdByName (user.getName ( ));
if (null!=name){
//用户名重复了
return -1;
}
//假盐 还没加工
String salt = Long.toString(System.currentTimeMillis());
//假盐,因为数据库的盐还不是真正的盐 解密的时候需要再次加工
user.setSalt (salt);
String password = user.getPassword ( );
//MD5加密生成密文
String password1 = PasswordGenerateUtil.getPassword (user.getName ( ), password, salt, 2);
//加功后的密文
user.setPassword (password1);
Integer insert = userDao.insert (user);
return insert;
}
}
5. CustomRealm修改>MD5密码加密后再验证,非对称的密文无法逆转,只能再次加密
@Override
protected SimpleAuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
;
//加这一步的目的是在Post请求的时候会先进认证,然后在到请求
if (null == authenticationToken.getPrincipal ( )) {
return null;
}
System.out.println ("执行认证逻辑" + getName ( ));
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
//获取用户登陆的名
String name = token.getUsername ( );
//查出的密码和盐封装成User
User user = userService.getPwdByName (name);
if (null == user) {
//用户名不存在
return null;//抛出一个空的对象 抛出异常UnknowAccountException
}
//密码
String pwd = user.getPassword ( );
//盐
String salt = user.getSalt ( );
//真盐=name+salt
salt = name + salt;
//这里验证authenticationToken和simpleAuthenticationInfo的信息
return new SimpleAuthenticationInfo (name, pwd, ByteSource.Util.bytes (salt), getName ( ));
}
}
6.测试创建一个用户wang5 ,密码123456 角色 rid=2,3
@SpringBootTest
class ShiroApplicationTests {
@Autowired
UserService userService;
@Autowired
RoleService roleService;
@Test
void contextLoads() {
User user = new User ( );
user.setName ("wang5");
user.setPassword ("123456");
Integer result = userService.insert (user);
if (result.equals ("1")) {
System.out.println ("插入成功");
} else {
System.out.println ("插入失败,可能是用户名重复:" + result);
}
}
@Test
void test(){
User wang5 = userService.getPwdByName ("wang5");
if (null==wang5) return;
Integer[] rids={2,3};
Integer integer = roleService.insert (rids, (int) wang5.getId ( ));
System.out.println("插入角色数量:"+integer);
}
}