2012-11-19 67 views
4

我们使用两个领域(一个用于散列密码,另一个用于生成明文密钥) - 这是按预期工作的。Apache Shiro:异常处理与多领域

只有一个领域,我们可以在我们的领域protected AuthenticationInfo doGetAuthenticationInfo(final AuthenticationToken authToken)中抛出DisabledAccountException异常,并在我们的应用程序中明确地捕捉到这样的异常。

现在我们有两个领域,所有例外都是Shiro内部捕获的;所以如果一个领域失败了,第二个领域也可以尝试。但是,这种重定向只会将泛型AuthenticationExceptions引入我们的应用程序。

是否有任何解决方法与多个领域,以便我们可以有更具体的例外(要知道,如果一个帐户被锁定,证书是根本错误的......)?

回答

7

您需要指定您自己的AuthenticationStrategy您的ModularRealmAuthenticator。 的ModularRealmAuthenticator使用AtLeastOneSuccessfulStrategy默认和AtLeastOneSuccessfulStrategy忽略异常并不断尝试登录使用所有可用的领域的用户。

我们不得不对tynamo项目类似的场景和要解决这个问题,我已经实现了我自己AuthenticationStrategy,称为FirstExceptionStrategy,与多个领域的工作,并抛出它获得的第一个例外。这种方法工作正常,只要只有一个领域令牌类型

的实现是相当简单:

/** 
* {@link org.apache.shiro.authc.pam.AuthenticationStrategy} implementation that throws the first exception it gets 
* and ignores all subsequent realms. If there is no exceptions it works as the {@link FirstSuccessfulStrategy} 
* 
* WARN: This approach works fine as long as there is ONLY ONE Realm per Token type. 
* 
*/ 
public class FirstExceptionStrategy extends FirstSuccessfulStrategy { 

    @Override 
    public AuthenticationInfo afterAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo singleRealmInfo, AuthenticationInfo aggregateInfo, Throwable t) throws AuthenticationException { 
     if ((t != null) && (t instanceof AuthenticationException)) throw (AuthenticationException) t; 
     return super.afterAttempt(realm, token, singleRealmInfo, aggregateInfo, t); 
    } 

} 

我再说一遍,这只有作品,如果有每个令牌类型ONLY ONE境界。

我的特定方案欲了解更多信息请看这里:http://jira.codehaus.org/browse/TYNAMO-154

+0

不幸的是,我们正在使用''UsernamePasswordToken''的两个领域,因此这不会解决我们的问题......但感谢输入! – xeraa

+2

没有不同的_Tokens_,这个策略真的很难知道它是否应该抛出异常,或者应该继续查看领域列表。看看_ModularRealmAuthenticator.doMultiRealmAuthentication_。也许你可以在_beforeAllAttempts_中创建自己的聚合,将聚合中的异常保存在_afterAttempt_中,然后将异常保存在_afterAllAttempts_中。 – ascandroli

+0

感谢您的指点,但我认为这不值得。我们目前对通用例外情况良好,并会在我们需要额外信息的情况下尝试您的建议。 – xeraa