shiro多realm抛出异常问题

shiro多realm抛出异常问题

关于这个问题百度会搜到很多内容,但是大多数都不全,只是提到了一部分内容,所以综合本人以及网上搜到的内容,提出如下解决方案:

我是使用了两个Realm,一个用于用户登录验证和访问权限获取;一个用于jwt token的认证,所以出现了
Authentication token of type [class org.apache.shiro.authc.Username
PasswordToken] could not be authenticated by any configured realms.
其中涉及到的原理方面的东西我就不多说了,网上讲的比我清楚,我这里直接贴出全部的解决代码:
1.在每个realm中都要有support方法的重写:

 @Override
public boolean supports(AuthenticationToken token) {
    return token instanceof JwtToken;
}
  @Override
public boolean supports(AuthenticationToken token) {
    return token instanceof UsernamePasswordToken;
}

2.自定义一个类继承ModularRealmAuthenticator,并重写doMultiRealmAuthentication方法:

 private static final Logger log = LoggerFactory.getLogger(MyModularRealmAuthenticator.class);

    @Override
    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());
        }
        AuthenticationException authenticationException = null;
        for (Realm realm : realms) {

            aggregate = strategy.beforeAttempt(realm, token, aggregate);

            if (realm.supports(token)) {

                log.trace("Attempting to authenticate token [{}] using realm [{}]", token, realm);

                AuthenticationInfo info = null;
                try {
                    info = realm.getAuthenticationInfo(token);
                } catch (AuthenticationException e) {
                    authenticationException = e;
                    if (log.isDebugEnabled()) {
                        String msg = "Realm [" + realm + "] threw an exception during a multi-realm authentication attempt:";
                        log.debug(msg, e);
                    }
                }

                aggregate = strategy.afterAttempt(realm, token, info, aggregate, authenticationException);

            } else {
                log.debug("Realm [{}] does not support token {}.  Skipping realm.", realm, token);
            }
        }
        if(authenticationException != null){
            throw authenticationException;
        }
        aggregate = strategy.afterAllAttempts(token, aggregate);

        return aggregate;

    }

3.在shiro的配置类中注入自定义类(大多数网上都缺少这部分内容)

 @Bean
    public Authenticator authenticator() {

        ModularRealmAuthenticator authenticator = new MyModularRealmAuthenticator();

        authenticator.setRealms(Arrays.asList(shiroRealm(), loginRealm()));
        authenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());
        return authenticator;
    }

    @Bean("securityManager")
    public DefaultSecurityManager securityManager(){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //设置自定义realm
        Set<Realm> realms = new HashSet<Realm>();
        realms.add(shiroRealm());
        realms.add(loginRealm());
        securityManager.setRealms(realms);
        //关闭shiro自带的session
        DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
        DefaultSessionStorageEvaluator sessionStorageEvaluator = new DefaultSessionStorageEvaluator();
        sessionStorageEvaluator.setSessionStorageEnabled(false);
        subjectDAO.setSessionStorageEvaluator(sessionStorageEvaluator);
        securityManager.setSubjectDAO(subjectDAO);
        securityManager.setAuthenticator(authenticator());//解决多realm的异常问题重点在此
        return securityManager;
    }
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值