//步骤1:首先利用工具类获取Subject,没有获取到则创建一个新的Subject
Subject currentUser = SecurityUtils.getSubject();
//步骤2:在默认实现类DelegatingSubject中执行登录验证过程
public void login(AuthenticationToken token) throws AuthenticationException {
//只列出核心代码
//调用 securityManager验证登录
Subject subject = securityManager.login(this, token);
PrincipalCollection principals;
String host = null;
//登录成功后获取用户实体类
if (subject instanceof DelegatingSubject) {
DelegatingSubject delegating = (DelegatingSubject) subject;
principals = delegating.principals;
host = delegating.host;
} else {
principals = subject.getPrincipals();
}
}
现在分析 Subject subject = securityManager.login(this, token);执行过程
在DefaultSecurityManager实现类中
public Subject login(Subject subject, AuthenticationToken token) throws AuthenticationException {
AuthenticationInfo info;
try {
//验证token
info = authenticate(token);
} catch (AuthenticationException ae) {
try {
onFailedLogin(token, ae, subject);
} catch (Exception e) {
if (log.isInfoEnabled()) {
log.info("onFailedLogin method threw an " +
"exception. Logging and propagating original AuthenticationException.", e);
}
}
throw ae; //propagate
}
Subject loggedIn = createSubject(token, info, subject);
onSuccessfulLogin(token, info, loggedIn);
return loggedIn;
}
看看方法authenticate(token),该方法在父类 AuthenticatingSecurityManager中,下面的继承上面的类,继承结构为
interface SecurityManager, Destroyable, CacheManagerAware, EventBusAware
abstract CachingSecurityManager
abstract RealmSecurityManager
abstract AuthenticatingSecurityManager
abstract AuthorizingSecurityManager
class SessionsSecurityManager
class DefaultSecurityManager
public AuthenticationInfo authenticate(AuthenticationToken token) throws AuthenticationException {
//利用authenticator去验证
return this.authenticator.authenticate(token);
}
securityManager内容关于认证代码全部依赖类 Authenticator 去验证
public AuthenticatingSecurityManager() {
super();
this.authenticator = new ModularRealmAuthenticator();
}
默认实现类为 ModularRealmAuthenticator ,继承结构为
interface Authenticator, LogoutAware
abstract AbstractAuthenticator
class ModularRealmAuthenticator
其中AbstractAuthenticator,该类实现了自定义注册验证失败通知类,方便用户处理验证失败, 该类中实现了接口Authenticator的方法:
public final AuthenticationInfo authenticate(AuthenticationToken token) throws AuthenticationException {
//已删除非核心代码
AuthenticationInfo info;
try {
//调用模板方法,子类实现,这里的子类就是 ModularRealmAuthenticator
info = doAuthenticate(token);
if (info == null) {
throw new AuthenticationException(msg);
}
} catch (Throwable t) {
AuthenticationException ae = null;
if (t instanceof AuthenticationException) {
ae = (AuthenticationException) t;
}
if (ae == null) {
ae = new AuthenticationException(msg, t);
}
try {
//通知注册的类失败
notifyFailure(token, ae);
} catch (Throwable t2) {
}
}
throw ae;
}
notifySuccess(token, info);
return info;
}
子类 ModularRealmAuthenticator方法:
protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException {
assertRealmsConfigured();
Collection<Realm> realms = getRealms();
if (realms.size() == 1) {
return doSingleRealmAuthentication(realms.iterator().next(), authenticationToken);
} else {
return doMultiRealmAuthentication(realms, authenticationToken);
}
}
可以看出,实际执行验证的是接口Realm的实现类,继承机构:
interface Realm, Nameable, CacheManagerAware, LogoutAware
abstract CachingRealm
abstract class AuthenticatingRealm
abstract class AuthorizingRealm
先分析doSingleRealmAuthentication(realms.iterator().next(), authenticationToken);
protected AuthenticationInfo doSingleRealmAuthentication(Realm realm, AuthenticationToken token) {
if (!realm.supports(token)) {
throw new UnsupportedTokenException(msg);
}
AuthenticationInfo info = realm.getAuthenticationInfo(token);
if (info == null) {
throw new UnknownAccountException(msg);
}
return info;
}
所以看到了吧,只要继承 AuthorizingRealm 类,实现里面的getAuthenticationInfo就可以了。