(一)md5散列加密
  一般来说,我们后端会将前端接收到的密码进行加密,再存进数据库中,所以这里的逻辑主要发生在存入数据库之前。

public class CustomRealmTest {
@Test
public void testCustomRealm(){
CustomRealm customRealm = new CustomRealm();
DefaultSecurityManager securityManager = new DefaultSecurityManager();
securityManager.setRealm(customRealm);

//1、设置加密对象HashedCredentialsMatcher
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
//2、加密算法
matcher.setHashAlgorithmName("md5");
//3、加密次数
matcher.setHashIterations(1);
//4、为Realm设置加密对象
customRealm.setCredentialsMatcher(matcher);


SecurityUtils.setSecurityManager(securityManager);
Subject subject = SecurityUtils.getSubject();
AuthenticationToken token = new UsernamePasswordToken("root", "root");
subject.login(token);
System.out.println(subject.isAuthenticated());
subject.checkRoles("admin", "guest");

subject.checkPermission("user:delete");
}
}

(二)md5散列+盐值加密
  “md5散列”不用多说,参见上面。
  盐值加密,说白了,就是将用户密码进行md5散列之后,再一次进行加密(PS:这里涉及到MD5散列的缺点,可能无法通过md5散列码反推出原密码,但是可以通过字符串进行md5散列再进行比对,可反推出密码)。若数据库中的密码进行过盐值加密,则需要在数据源Realm中,将盐值设置到​​​SimpleAuthenticationInfo​​中,这样在密码比对的时候,前端的密码在散列后,再进行盐值加密,再进行比对!

/**
* 认证验证(返回数据库中真实的用户名、密码)
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String username = (String)token.getPrincipal();
String password = getPasswordByUsername(username);
if (password == null){
return null;
}
//参数一:用户名 参数二:密码 参数三:自定义Realm的名称(在构造函数中设置名称super.setName("customRealm"))
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username, password, "customRealm");

//在返回AuthenticationInfo对象之前,设置盐!!!
authenticationInfo.setCredentialsSalt(ByteSource.Util.bytes("mark"));
return authenticationInfo;
}