1、shiro认证流程源码分析
(1)输入用户名和密码进行登录
UsernamePasswordToken token=new UsernamePasswordToken(username,password);
(2)下一步
subject.login(token);
(3)查看login源码
public void login(AuthenticationToken token) throws AuthenticationException { this.clearRunAsIdentitiesInternal(); Subject subject = this.securityManager.login(this, token);//--------------- String host = null; PrincipalCollection principals; if (subject instanceof DelegatingSubject) { DelegatingSubject delegating = (DelegatingSubject)subject; principals = delegating.principals; host = delegating.host; } else { principals = subject.getPrincipals(); } if (principals != null && !principals.isEmpty()) { this.principals = principals; this.authenticated = true; if (token instanceof HostAuthenticationToken) { host = ((HostAuthenticationToken)token).getHost(); } if (host != null) { this.host = host; } Session session = subject.getSession(false); if (session != null) { this.session = this.decorate(session); } else { this.session = null; } } else { String msg = "Principals returned from securityManager.login( token ) returned a null or empty value. This value must be non null and populated with one or more elements."; throw new IllegalStateException(msg); } }
(4)查看securityManager.login(安全管理器)
public Subject login(Subject subject, AuthenticationToken token) throws AuthenticationException { AuthenticationInfo info; try { info = this.authenticate(token); } catch (AuthenticationException var7) { AuthenticationException ae = var7; try { this.onFailedLogin(token, ae, subject); } catch (Exception var6) { if (log.isInfoEnabled()) { log.info("onFailedLogin method threw an exception. Logging and propagating original AuthenticationException.", var6); } } throw var7; } Subject loggedIn = this.createSubject(token, info, subject); this.onSuccessfulLogin(token, info, loggedIn); return loggedIn; }
(5)查看authenticate(安全管理器)
public AuthenticationInfo authenticate(AuthenticationToken token) throws AuthenticationException { return this.authenticator.authenticate(token); }
(6)authenticator.authenticate(认证器)
public final AuthenticationInfo authenticate(AuthenticationToken token) throws AuthenticationException { if (token == null) { throw new IllegalArgumentException("Method argument (authentication token) cannot be null."); } else { log.trace("Authentication attempt received for token [{}]", token); AuthenticationInfo info; try { info = this.doAuthenticate(token); if (info == null) { String msg = "No account information found for authentication token [" + token + "] by this Authenticator instance. Please check that it is configured correctly."; throw new AuthenticationException(msg); } } catch (Throwable var8) { AuthenticationException ae = null; if (var8 instanceof AuthenticationException) { ae = (AuthenticationException)var8; } if (ae == null) { String msg = "Authentication failed for token submission [" + token + "]. Possible unexpected error? (Typical or expected login exceptions should extend from AuthenticationException)."; ae = new AuthenticationException(msg, var8); if (log.isWarnEnabled()) { log.warn(msg, var8); } } try { this.notifyFailure(token, ae); } catch (Throwable var7) { if (log.isWarnEnabled()) { String msg = "Unable to send notification for failed authentication attempt - listener error?. Please check your AuthenticationListener implementation(s). Logging sending exception and propagating original AuthenticationException instead..."; log.warn(msg, var7); } } throw ae; } log.debug("Authentication successful for token [{}]. Returned account [{}]", token, info); this.notifySuccess(token, info); return info; } }
(7)doAuthenticate
在这里完成realm的加载
protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException { this.assertRealmsConfigured();//确认配置了realm Collection<Realm> realms = this.getRealms();//或取到所有的realm return realms.size() == 1 ? this.doSingleRealmAuthentication((Realm)realms.iterator().next(), authenticationToken) :
this.doMultiRealmAuthentication(realms, authenticationToken);//realms就是认证的时候会执行的realm }//一个realm就执行单realm认证,否则执行多realm认证