[ https://issues.apache.org/jira/browse/SHIRO-769?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17401122#comment-17401122 ]
Benjamin Marwell commented on SHIRO-769: ---------------------------------------- Hi [~gexiuyu]. Please kindly report back if another realm strategy (as proposed by [~bdemers]) solved your issue. I might close this issue as stale otherwise. Thanks :) > 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 > Priority: Critical > > 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)