认证/授权基本步骤
①获取当前的 Subject,调用SecurityUtils.getSubject();
②判断当前用户是否已经认证,调用 Subject 的 isAuthenticated();
③或没有被认证,则把用户名和密码封装为 UserNamePassworkToken 对象
[1]客户端提交的表单数据。
[2]提交数据到SpringMVC的 handler 上。
[3]获取用户名和密码。
④执行登录,调用 Subject 的 login(AuthencationToken);
⑤自定义Realm 方法,从数据库中获用户安全数据,
1.使用token的用户名去数据库中查询数据返回(SimpleAuthenticationInfo)给Shiro
[1]实际上需要继承
org.apache.shiro.realm.AuthencatingRealm 类(仅仅实现认证,
org.apache.shiro.realm.AuthorizingRealm 可以用来认证和授权)。
[2]实现 doGetAuthenticationInfo(AuthenticationToken) 方法。
⑥最后由Shiro完成密码的比对。
密码的匹配
最终使用HashedCredentialsMatcher类的doCredentialsMatch()方法进行密码的比对,此方法包含两个参数AuthenticationToken token, AuthenticationInfo info,思路一下子豁然开朗。
@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
Object tokenHashedCredentials =
hashProvidedCredentials(token, info);
Object accountCredentials = getCredentials(info);
return equals(tokenHashedCredentials, accountCredentials);
}
方法的最后通过一个equals函数进行散列的比较:
//equals()方法的主要代码:
byte[] tokenBytes = toBytes(tokenCredentials);
byte[] accountBytes = toBytes(accountCredentials);
return Arrays.equals(tokenBytes, accountBytes);
验证完毕,最后执行subject.login(token)登录成功。