rk_svnadmin/src/main/java/com/rekoe/shiro/ModularRealmAuthenticator2....

74 lines
2.7 KiB
Java

package com.rekoe.shiro;
import java.util.Collection;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.pam.AuthenticationStrategy;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.realm.Realm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 改变Shiro原生的ModularRealmAuthenticator在多个Realm时的行为,如果仅一个Realm识别Token,那么行为跟单个Realm时一致
* @author wendal
*
*/
public class ModularRealmAuthenticator2 extends ModularRealmAuthenticator {
private static final Logger log = LoggerFactory.getLogger(ModularRealmAuthenticator.class);
/**
* 官方实现里面, 如果有多个Realm,无论是不是只有一个Realm适合当前的AuthenticationToken,授权失败的时候都会抛出一个令人费解的异常
*/
protected AuthenticationInfo doMultiRealmAuthentication(Collection<Realm> realms, AuthenticationToken token) {
AuthenticationStrategy strategy = getAuthenticationStrategy();
AuthenticationInfo aggregate = strategy.beforeAllAttempts(realms, token);
if (log.isTraceEnabled()) {
log.trace("Iterating through {} realms for PAM authentication", realms.size());
}
Throwable t = null;
int count = 0;
Realm _realm = null;
for (Realm realm : realms) {
if (realm.supports(token)) {
count ++;
_realm = realm;
log.trace("Attempting to authenticate token [{}] using realm [{}]", token, realm);
AuthenticationInfo info = null;
try {
info = realm.getAuthenticationInfo(token);
} catch (Throwable throwable) {
t = throwable;
if (log.isDebugEnabled()) {
String msg = "Realm [" + realm + "] threw an exception during a multi-realm authentication attempt:";
log.debug(msg, t);
}
}
aggregate = strategy.afterAttempt(realm, token, info, aggregate, t);
} else {
log.debug("Realm [{}] does not support token {}. Skipping realm.", realm, token);
}
}
if (count == 1 && t != null) {
String msg = "Realm [" + _realm + "] was unable to find account data for the " +
"submitted AuthenticationToken [" + token + "].";
throw new UnknownAccountException(msg);
}
aggregate = strategy.afterAllAttempts(token, aggregate);
return aggregate;
}
}