4

我们正在使用两个领域(一个用于散列密码,另一个用于生成的明文密钥) - 这按预期工作。

对于单个领域,我们可以DisabledAccountException在我们的领域中抛出一个异常,protected AuthenticationInfo doGetAuthenticationInfo(final AuthenticationToken authToken)并在我们的应用程序中显式捕获这样的异常。

现在我们有了两个领域,所有异常都被 Shiro 内部捕获;所以如果一个境界失败了,也可以尝试第二个境界。但是,这种重定向只会AuthenticationExceptions对我们的应用程序抛出泛型。

是否有多个领域的解决方法,以便我们可以有更具体的例外(要知道一个帐户是否被锁定,凭据是否完全错误,......)?

4

1 回答 1

7

您需要在ModularRealmAuthenticator中指定自己的AuthenticationStrategy。ModularRealmAuthenticator默认使用AtLeastOneSuccessfulStrategy并且AtLeastOneSuccessfulStrategy忽略异常并继续尝试使用所有可用领域登录用户。

我们在tynamo项目中有一个类似的场景,为了解决这个问题,我实现了我自己的AuthenticationStrategy,称为FirstExceptionStrategy,它适用于多个领域并抛出它得到的第一个异常。只要每个Token type只有一个Realm ,这种方法就可以正常工作。

实现相当简单:

/**
 * {@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);
    }

}

我再说一遍,这只有在每个 Token 类型只有一个Realm 时才有效。

有关我的特定场景的更多信息,请参见此处:http: //jira.codehaus.org/browse/TYNAMO-154

于 2012-11-19T12:15:03.743 回答