[
https://issues.apache.org/jira/browse/SHIRO-769?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17101722#comment-17101722
]
Brian Demers commented on SHIRO-769:
------------------------------------
Thanks [~gexiuyu]!
When it comes to supporting multiple realms, Shiro provides a few strategies,
for example, take a look at the AllSuccessfulStrategy (you can plug a custom
strategy into the ModularReamAuthenticator).
When you have multiple realms, and you have the same account in both realms,
one of them is disabled, and the other is fine, what should happen is likely
implementation-specific.
Take a look at the available auth strategies, and let us know if that works for
you
> 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)