| 
 | 
	
 
 
一直以为给定的下面配置是短路方式的,即defaultJdbcRealm可以成功认证,backDoorJdbcRealm就不会被调用。 
其实不然,org.apache.shiro.authc.pam.FirstSuccessfulStrategy并不是这个意思,所有的realm依然都会被调用。 
只不过是第一个认证成功的AuthenticationInfo作为最后的结果返回。 
 
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> 
<!-- 其他配置 --> 
<property name="authenticator" ref="authenticator" /> 
<property name="realms"> 
<list> 
<ref bean="defaultJdbcRealm" /> 
<ref bean="backDoorJdbcRealm" /> 
</list> 
</property> 
</bean> 
<bean id="defaultJdbcRealm" class="..." /> 
<bean id="backDoorJdbcRealm" class="..." /> 
<bean id="authenticator" class="org.apache.shiro.authc.pam.ModularRealmAuthenticator"> 
<property name="authenticationStrategy"> 
<bean class="org.apache.shiro.authc.pam.FirstSuccessfulStrategy" /> 
</property> 
</bean> 
 
 
为了实现目的,必须对org.apache.shiro.authc.pam.ModularRealmAuthenticator改造。 
 
package xxx.yyy.security; 
import java.util.Collection; 
import org.apache.shiro.authc.AuthenticationInfo; 
import org.apache.shiro.authc.AuthenticationToken; 
import org.apache.shiro.authc.pam.AuthenticationStrategy; 
import org.apache.shiro.realm.Realm; 
import org.apache.shiro.util.CollectionUtils; 
public class ModularRealmAuthenticator extends org.apache.shiro.authc.pam.ModularRealmAuthenticator { 
@Override 
protected AuthenticationInfo doMultiRealmAuthentication(Collection<Realm> realms, AuthenticationToken token) { 
AuthenticationStrategy strategy = getAuthenticationStrategy(); 
AuthenticationInfo aggregate = strategy.beforeAllAttempts(realms, token); 
for (Realm realm : realms) { 
aggregate = strategy.beforeAttempt(realm, token, aggregate); 
if (realm.supports(token)) { 
AuthenticationInfo info = null; 
Throwable t = null; 
try { 
info = realm.getAuthenticationInfo(token); 
} catch (Throwable throwable) { 
t = throwable; 
} 
aggregate = strategy.afterAttempt(realm, token, info, aggregate, t); 
// dirty dirty hack 
if (aggregate != null && !CollectionUtils.isEmpty(aggregate.getPrincipals())) { 
return aggregate; 
} 
// end dirty dirty hack 
} else { 
} 
} 
aggregate = strategy.afterAllAttempts(token, aggregate); 
return aggregate; 
} 
} 
 
 
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> 
<!-- 其他配置 --> 
<property name="authenticator" ref="authenticator" /> 
<property name="realms"> 
<list> 
<ref bean="defaultJdbcRealm" /> 
<ref bean="backDoorJdbcRealm" /> 
</list> 
</property> 
</bean> 
<bean id="defaultJdbcRealm" class="..." /> 
<bean id="backDoorJdbcRealm" class="..." /> 
<bean id="authenticator" class="xxx.yyy.security.ModularRealmAuthenticator"> 
<property name="authenticationStrategy"> 
<bean class="org.apache.shiro.authc.pam.FirstSuccessfulStrategy" /> 
</property> 
</bean> |   
 
 
 
 |