Uploaded image for project: 'Shiro'
  1. Shiro
  2. SHIRO-769

Multiple realm exceptions cannot be catch

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Critical
    • Resolution: Information Provided
    • Affects Version/s: 1.5.3
    • Fix Version/s: None
    • Component/s: Realms
    • Labels:
    • Environment:
      jdk8

      Description

      I have multiple realm, one of them

      //代码占位符
      @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());
      }
      

      but can catch DisabledAccountException ,ExpiredCredentialsException and IncorrectCredentialsException 

       

      //代码占位符
      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("验证码错误");
      }
      

       

      In class ModularRealmAuthenticator, why not get realm exception first?

       

      This is my extension and it works fine

      //代码占位符
      @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;
          }
      }
      

       

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              gexiuyu XiuYu.GE
            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: