Shiro集成多个Realm,认证都不通过返回y configured realms. Please ensure that at least one realm can authenticate these tokens.

异常内容:Authentication token of type [class org.apache.shiro.authc.UsernamePasswordToken] could not be authenticated by any configured realms. Please ensure that at least one realm can authenticate these tokens.

意思是没有Realm进行处理,但实际上是当配置了多个realm时,就会 org.apache.shiro.authc.pam.ModularRealmAuthenticator#doMultiRealmAuthentication 通过这个方法进行执行,如果所有的对应的realm都返回认证异常或者null的话,就会出现以上错误

解决办法

第一种  集成ModularRealmAuthenticator重写doMultiRealmAuthentication方法

第二种,重写Authenticator的认证策略,由于ModularRealmAuthenticator默认是配置的这个 AtLeastOneSuccessfulStrategy策略,那么重写以下方法,当异常是认证异常时,则进行抛出认证异常

public class MyAtLeastOneSuccessfulStrategy extends AtLeastOneSuccessfulStrategy {

    @Override
    public AuthenticationInfo afterAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo singleRealmInfo, AuthenticationInfo aggregateInfo, Throwable t) throws AuthenticationException {
        if(t instanceof AuthenticationException){
            throw (AuthenticationException)t;
        }
        return super.afterAttempt(realm, token, singleRealmInfo, aggregateInfo, t);
    }

    public static void main(String[] args) {
        Provider[] providers = Security.getProviders();
        System.out.println(providers);
    }

}

 

 根据所需抛出的异常时机,重写以上方法即可,方法作用直接看doc就能明白

 

 

那么最关键的怎么配置呢?

 

 这2个shiro的配置类,至少我这边没有使用上,如果你的代码使用了,继承此类重写对应的方法返回的实例即可。

而我是这么解决的。

对应的Shiro的配置示例:

  @Bean
  public SecurityManager securityManager(UserRealm userRealm, ApiAuthenticationRealm apiAuthenticationRealm) {
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
    // 设置realm.
    securityManager.setRealms(Arrays.asList(userRealm, apiAuthenticationRealm));

    ......

    Authenticator authenticator = securityManager.getAuthenticator();
    if(authenticator instanceof ModularRealmAuthenticator){
      ModularRealmAuthenticator modularRealmAuthenticator = (ModularRealmAuthenticator) authenticator;
      modularRealmAuthenticator.setAuthenticationStrategy(new MyAtLeastOneSuccessfulStrategy());
    }
//    securityManager.setAuthenticator();

    return securityManager;
  }

 

posted @ 2021-05-17 13:57  星小梦  阅读(2813)  评论(1编辑  收藏  举报