- 认证
- Subject 调用 login 方法,传入一个 UsernamePasswordToken(封装有账号密码)
- Subject 有一个 叫DelegatingSubject 的实现类,这个子类有一个 SecurityManager 类型的成员变量, DelegatingSubject 的 login 调用的就是 SecurityManager 的login方法
public void login(AuthenticationToken token) throws AuthenticationException {
……
Subject subject = securityManager.login(this, token);
//这一句就是调用 SecurityManager 的login 方法,把UsernamePasswordToken 传进去了
……
-
- SecurityManager 有一个 DefaultSecurityManager 实现类,DelegatingSubject 实际上调用的就是DefaultSecurityManager 的login 方法,传入的还是 UsernamePasswordToken
public Subject login(Subject subject, AuthenticationToken token) throws AuthenticationException {
AuthenticationInfo info;
try {
info = authenticate(token);
……
}
-
- 关键就是这个authenticate方法,它调用的是AuthenticatingSecurityManager 这个类的 authenticate 方法,
public AuthenticationInfo authenticate(AuthenticationToken token) throws AuthenticationException {
return this.authenticator.authenticate(token);
}
-
- 下边这个就是 AuthenticatingSecurityManager 的 authenticate 方法了,这个类有一个Authenticator 类型的成员变量,AuthenticatingSecurityManager类的 authenticate 方法调用的就是 authenticator的authenticate方法,把最开始的UsernamePasswordToken传了进去
public AuthenticationInfo authenticate(AuthenticationToken token) throws AuthenticationException {
return this.authenticator.authenticate(token);
}
-
- Authenticator 有一个实现了类是 AbstractAuthenticator,调用的这个authenticate 方法实际上是调到了AbstractAuthenticator 的 authenticate 方法
public final AuthenticationInfo authenticate(AuthenticationToken token) throws AuthenticationException {
……
log.trace("Authentication attempt received for token [{}]", token);
AuthenticationInfo info;
try {
info = doAuthenticate(token);
……
}
-
- 那么实际上调用的就是 doAuthenticate 方法了,这个方法是 AbstractAuthenticator 的子类 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);
}
}
这个 doAuthenticate 会去遍历所有的 Realm, 然后执行它们的认证方法。
- 认证
- 只要写一个类实现 AuthorizingRealm, 重写 doGetAuthorizationInfo 方法就可以了
- 入口就是 hasRole 方法, 它调用的就是Subject 的 hasRole 方法,它有一个实现类DelegatingSubject,具体的 hasRole 方法就是在DelegatingSubject实现的,这个方法的具体实现是
- 只要写一个类实现 AuthorizingRealm, 重写 doGetAuthorizationInfo 方法就可以了
public boolean hasRole(String roleIdentifier){
return this.hasPrincipals() && this.securityManager.hasRole(this.getPrincipals(), roleIdentifier);
}
-
- 它调用就是securityManager.hasRole,hasRole实际上是 Authorizer 接口的一个方法,它有一个实现类 AuthorizingRealm,具体的 securityManager.hasRole 是在 AuthorizingRealm 执行的
public boolean hasRole (PrincipalCollection principal, String roleIdentifier){
AuthorizationInfo info = this.getAuthorizationInfo(principal);
return this.hasRole(roleIdentifier, info);
}
-
- 它其实调用的本类的getAuthorizationInfo 方法
protected AuthorizationInfo getAuthorizationInfo(PrincipalCollection principals) {
if (info == null) {
info = this.doGetAuthorizationInfo(principals);
if (info != null && cache != null) {
if (log.isTraceEnabled()) {
log.trace("Caching authorization info for principals:
……
}
}
-
- 这个方法关键的一句就是 doGetAuthorizationInfo, 这个方法是抽象的,恰恰就是我们重写的那个方法