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; } }