subject.login(token);
接着调用DelegatingSubject的login(AuthenticationToken token)
在该方法中调用 Subject subject = securityManager.login(this, token);
接着调用DefaultSecurityManager的
public Subject login(Subject subject, AuthenticationToken token)
throws AuthenticationException
{
AuthenticationInfo info;
try
{
info = authenticate(token);
}
4.其实是调用AuthenticatingSecurityManager的
public AuthenticationInfo authenticate(AuthenticationToken token)
throws AuthenticationException
{
return authenticator.authenticate(token);
}
5.authenticator默认为authenticator = new ModularRealmAuthenticator();
6.调用ModularRealmAuthenticator父类AbstractAuthenticator的
public final AuthenticationInfo authenticate(AuthenticationToken token)
throws AuthenticationException
{
if(token == null)
throw new IllegalArgumentException("Method argumet (authentication token) cannot be null.");
log.trace("Authentication attempt received for token [{}]", token);
AuthenticationInfo info;
try
{
info = doAuthenticate(token);
7.方法如下:
protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException { assertRealmsConfigured(); Collection realms = getRealms(); if(realms.size() == 1) return doSingleRealmAuthentication((Realm)realms.iterator().next(), authenticationToken); else return doMultiRealmAuthentication(realms, authenticationToken); }
8.doSingleRealmAuthentication的详细过程如下:
protected AuthenticationInfo doSingleRealmAuthentication(Realm realm, AuthenticationToken token) { if(!realm.supports(token)) { String msg = (new StringBuilder()).append("Realm [").append(realm).append("] does not support authentication token [").append(token).append("]. Please ensure that the appropriate Realm implementation is ").append("configured correctly or that the realm accepts AuthenticationTokens of this type.").toString(); throw new UnsupportedTokenException(msg); } AuthenticationInfo info = realm.getAuthenticationInfo(token); if(info == null) { String msg = (new StringBuilder()).append("Realm [").append(realm).append("] was unable to find account data for the ").append("submitted AuthenticationToken [").append(token).append("].").toString(); throw new UnknownAccountException(msg); } else { return info; } }
9.接着调用realm的getAuthenticationInfo(token)方法
该方法为父类public abstract class AuthenticatingRealm extends CachingRealm
中的方法
public final AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { AuthenticationInfo info = getCachedAuthenticationInfo(token); if(info == null) { info = doGetAuthenticationInfo(token);//根据用户名获取相关的用户信息 log.debug("Looked up AuthenticationInfo [{}] from doGetAuthenticationInfo", info); if(token != null && info != null) cacheAuthenticationInfoIfPossible(token, info); } else { log.debug("Using cached authentication info [{}] to perform credentials matching.", info); } if(info != null) assertCredentialsMatch(token, info);//具体的验证过程 else log.debug("No AuthenticationInfo found for submitted AuthenticationToken [{}]. Returning null.", token); return info; }
10.
doGetAuthenticationInfo
可以在具体子类中实现:
public class SimpleAccountRealm extends AuthorizingRealm { protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { UsernamePasswordToken upToken = (UsernamePasswordToken)token; SimpleAccount account = getUser(upToken.getUsername()); if(account != null) { if(account.isLocked()) throw new LockedAccountException((new StringBuilder()).append("Account [").append(account).append("] is locked.").toString()); if(account.isCredentialsExpired()) { String msg = (new StringBuilder()).append("The credentials for account [").append(account).append("] are expired").toString(); throw new ExpiredCredentialsException(msg); } } return account; }