XiuYu.GE created SHIRO-769:
------------------------------

             Summary: Multiple realm exceptions cannot be catch
                 Key: SHIRO-769
                 URL: https://issues.apache.org/jira/browse/SHIRO-769
             Project: Shiro
          Issue Type: Bug
          Components: Realms 
    Affects Versions: 1.5.3
         Environment: jdk8
            Reporter: XiuYu.GE


I have multiple realm, one of them
{code:java}
//代码占位符
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken 
authenticationToken) throws AuthenticationException {
    IphoneCodeToken iphoneCodeToken = (IphoneCodeToken)authenticationToken;
    MemberService memberService = SpringUtils.getBean(MemberService.class);
    Member member = memberService.findByMember(new 
Member().setMobilePhone(iphoneCodeToken.getIphone()));

    RedisUtil redisUtil = SpringUtils.getBean(RedisUtil.class);
    Object ipheonCodeNumObj = 
redisUtil.get(String.format(MEM_VERIFY_CODE.getKey(), 
iphoneCodeToken.getIphone()));
    //是否存在验证码
    if(ipheonCodeNumObj == null){
        throw new IncorrectCredentialsException();
    }

    //是否过期
    VerifyCodeData verifyCodeData = (VerifyCodeData)ipheonCodeNumObj;
    if(verifyCodeData.getTimestamp() < System.currentTimeMillis()){
        throw new ExpiredCredentialsException();
    }

    //验证码错误
    if(!verifyCodeData.getCode().equals(iphoneCodeToken.getCode())){
        throw new IncorrectCredentialsException();
    }

    //说明账号不存在
    if(member == null){
        throw new UnknownAccountException();
    }

    //是否为禁用
    if(member.getEnable().equals(MemberConstant.MemberStatus.DISENABLE)){
        throw new DisabledAccountException();
    }

    //设置到
    CurrUser currUser = new CurrUser();
    BeanUtils.copyProperties(member,currUser);
    SessionUtils.setInfo(currUser);
    return new 
SimpleAuthenticationInfo(iphoneCodeToken.getIphone(),iphoneCodeToken.getCode(),this.getClass().getName());
}
{code}
but can catch DisabledAccountException ,ExpiredCredentialsException and 
IncorrectCredentialsException 

 
{code:java}
//代码占位符
try {
    subject.login(new IphoneCodeToken(loginData.getIphone(), 
loginData.getCode()));
} catch (DisabledAccountException ee) {
    //主要考虑已注册就被禁用
    return ResultBean.error("账号被禁用");
} catch (ExpiredCredentialsException ee) {
    return ResultBean.error("验证码已过期");
} catch (IncorrectCredentialsException ee) {
    return ResultBean.error("验证码错误");
}
{code}
 

In class *ModularRealmAuthenticator*, why not get realm exception first?

 

This is my extension and it works fine
{code:java}
//代码占位符
@Slf4j
public class FruitsModularRealmAuthenticator  extends ModularRealmAuthenticator 
{

    @Override
    protected AuthenticationInfo doMultiRealmAuthentication(Collection<Realm> 
realms, AuthenticationToken token) throws AuthenticationException {
        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);
            }
        }
        //这里 如果方法内抛出异常,但是会不处理直接走向下面
        //下面的逻辑是获取授权的验证结果,由于这里抛出异常,
        // 所以获取的验证结果是空,则会认为没有支持的realm
        // 所以这里提前抛出异常
        if(authenticationException != null){
            throw authenticationException;
        }

        aggregate = strategy.afterAllAttempts(token, aggregate);

        return aggregate;
    }
}
{code}
 



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to