此篇文章是在Shiro整合Spring Boot入门的基础上写的,如果你没有shiro基础看不懂的话,可以去看看。
1、给Realm添加CredentialsMatcher
@Bean public UserRealm userRealm() { UserRealm userRealm = new UserRealm(); // 设置加密算法 HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher("md5"); // 设置加密次数 credentialsMatcher.setHashIterations(1); userRealm.setCredentialsMatcher(credentialsMatcher); return userRealm; }
在身份认证期间,Shiro会尝试使用credentialsMatcher去比对用户名密码是否正确。
2、保存在数据库中的密码也需要是加密后的密码
public class UserRealm extends AuthorizingRealm { // 模拟数据库中的数据 private Mapusers = new HashMap<>(); { // Realm中方法的密码必须也是加密过得 String password = new SimpleHash("md5", "123", "salt").toString(); users.put("xiaowang", new User("xiaowang", password, "user:add,user:update")); users.put("xiaoming", new User("xiaoming", password, "user:update")); } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { System.out.println("执行了认证=>doGetAuthenticationInfo"); UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken; // 模拟从数据库中根据用户名查用户信息 User user = users.get(token.getUsername()); if (user == null) { throw new UnknownAccountException(); } // 返回AuthenticationInfo中,还需要携带盐值 return new SimpleAuthenticationInfo(user, user.getPassword(), ByteSource.Util.bytes("salt"), ""); } 。。。 }
这里说明一下,为什么AuthenticationInfo要携带盐值。其实Shiro的比对规则是这样的,对用户输入的密码进行加密,然后与数据库中的密文进行比对,判断其是否相等。
所以有加盐的话,Shiro就需要知道盐是什么,而这个盐就从AuthenticationInfo获取。
最后来一个credentialsMatcher的使用案例:
public static void main(String[] args) { // 密码匹配器 HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher("md5"); // 设置加密次数 credentialsMatcher.setHashIterations(1); // 模拟用户登录输入的用户名密码 UsernamePasswordToken token = new UsernamePasswordToken("xiaowang", "123"); // 模拟从Realm中获取的认证信息 String password = new SimpleHash("md5", "123").toString(); SimpleAuthenticationInfo info = new SimpleAuthenticationInfo("xiaowang", password, ""); // 使用比较器比较 System.out.println(credentialsMatcher.doCredentialsMatch(token, info)); // 加盐 password = new SimpleHash("md5", "123", "salt").toString(); info = new SimpleAuthenticationInfo("xiaowang", password, ByteSource.Util.bytes("salt"), ""); System.out.println(credentialsMatcher.doCredentialsMatch(token, info)); }
码云地址
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)