shiro登录认证过程
登录方法
可以看到已经获取到了username、password和rememberMe ,为了接下来的认证过程,我们需要获取subject对象,也就是代表当前登录用户,并且要将username和password、rememberMe 两个变量设置到UsernamePasswordToken对象的token中, 调用SecurityUtils.getSubject().login(token)方法,将 token传入;
下面来看 subject.login(token)方法
主要通过securityManager安全管理器调用securityManager.login(this, token);方法,
下面来看
方法中定义了AuthenticationInfo对象来接受从Realm传来的认证信息,进入authenticate(token)方法中
继续跟进去,进入authenticator.authenticate(token)方法
再继续跟进去看doAuthenticate(token)方法的实现
其中,this.assertRealmsConfigured();是判断当前的realm是否存在,不存在则抛出异常
当前项目中只配置了一个realm,则会进入doSingleRealmAuthentication((Realm)realms.iterator().next(), authenticationToken)方法,并且会将 realm和token作为参数传入,这里的realm其实就是自己定义的UserRealm,继续进入doSingleRealmAuthentication方法
这里会先判断realm是否支持token,然后进入else方法执行realm.getAuthenticationInfo(token)方法,继续跟进
this.getCachedAuthenticationInfo(token)这个方法是从shiro缓存中读取用户信息,如果没有,才从realm中获取信息。如果是第一次登陆,缓存中肯定没有认证信息,所以会执行this.doGetAuthenticationInfo(token)这个方法,
在执行登录认证的时候需要选择我们自己实现的realm方法
读取数据库信息进行验证,并封装成SimpleAuthenticationInfo中返回
再次查看getAuthenticationInfo
assertCredentialsMatch(token, info)方法用于密码校验,点进去可以看到
cm.doCredentialsMatch(token, info)执行密码校验
点进去可以看到
通过从token中取出的密码与从数据库取出的info中的密码进行比较,认证相同返回true;失败就返回false,并抛出AuthenticationException,将info返回到defaultSecurityManager中,到此认证过程结束