2012-11-19 89 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