接之前的案例 在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);
}
}