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)