配置凭证匹配器
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher() {
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName("SHA-256");//散列算法:MD2、MD5、SHA-1、SHA-256、SHA-384、SHA-512等。
hashedCredentialsMatcher.setHashIterations(1);//散列的次数,默认1次, 设置两次相当于 md5(md5(""));
System.out.println("hasedCredentialMather:"+hashedCredentialsMatcher);
return hashedCredentialsMatcher;
}
之前的realm类和securityManager类需要稍作修改
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 设置realm.
securityManager.setRealm(customRealm(hashedCredentialsMatcher()));
//securityManager.setRealms(Arrays.asList(customRealm(hashedCredentialsMatcher()),jwtRealm()));
System.out.println("securityManager生成成功");
return securityManager;
}
@Bean
public CustomRealm customRealm(HashedCredentialsMatcher hashedCredentialsMatcher) {
CustomRealm customRealm=new CustomRealm();
customRealm.setCredentialsMatcher(hashedCredentialsMatcher);
System.out.println("customrealm生成成功");
return customRealm;
}
这样就把凭证匹配器注册到身份验证的 Realm 中,在用户进行登陆操作的时候,在 Realm 中的 doGetAuthenticationInfo 方法中使用这种方法进行用户身份认证:
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("customrealm----身份认证");
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
// 从数据库获取对应用户名密码的用户
User user = userMapper.selectbyUsername(token.getUsername());
String password="";
if(user!=null)
{password=user.getPassword();}
return new SimpleAuthenticationInfo(token.getPrincipal(), password, ByteSource.Util.bytes(token.getUsername()), getName());
}
shiroUtils工具类(生成加密密码)
/**
* 随机生成 salt 需要指定 它的字符串的长度
*
* @param len 字符串的长度
* @return salt
*/
public static String generateSalt(int len) {
//一个Byte占两个字节
int byteLen = len >> 1;
SecureRandomNumberGenerator secureRandom = new SecureRandomNumberGenerator();
return secureRandom.nextBytes(byteLen).toHex();
}
/**
* 获取加密后的密码,使用默认hash迭代的次数 1 次
*
* @param hashAlgorithm hash算法名称 MD2、MD5、SHA-1、SHA-256、SHA-384、SHA-512、etc。
* @param password 需要加密的密码
* @param salt 盐
* @return 加密后的密码
*/
public static String encryptPassword(String hashAlgorithm, String password, String salt) {
return encryptPassword(hashAlgorithm, password, salt, 1);
}
/**
* 获取加密后的密码,需要指定 hash迭代的次数
*
* @param hashAlgorithm hash算法名称 MD2、MD5、SHA-1、SHA-256、SHA-384、SHA-512、etc。
* @param password 需要加密的密码
* @param salt 盐
* @param hashIterations hash迭代的次数
* @return 加密后的密码
*/
public static String encryptPassword(String hashAlgorithm, String password, String salt, int hashIterations) {
SimpleHash hash = new SimpleHash(hashAlgorithm, password, salt, hashIterations);
return hash.toString();
}
测试
@RequestMapping("regist")
public int regist()
{
User user=new User();
user.setUsername("test7");
user.setPassword(ShiroUtils.encryptPassword("SHA-256", "123456","test7"));
return userMapper.insertSelective(user);
}
这里为了方便起见,没有把使用shiroUtils中generateSalt方法生成盐值,而是直接用username作为了盐值,如果要用generateSalt方法的话,还必须要在数据库中将生成的盐值保存。