2012-04-23 82 views
1

我的代碼當前正常工作正常執行SPNEGO(Kerberos)身份驗證爲我的網站的用戶。我有一個特殊的緩存機制來加速基於確認用戶身份的決定。對於普通的密碼認證來說,這很簡單 - 將「當前」用戶名+密碼組合與「舊」密碼組合比較 - 如果沒有變化,決策仍然可以被緩存。否則,他們需要重新評估。Java GSSAPI:比較兩個GSSCredential實例

我正在嘗試爲Kerberos做同樣的事情。我主要工作,但我很困惑爲什麼GSSCredential.equals()不會工作。特別是,在對每個請求進行身份驗證後,我獲得的GSSCredential實例是「相同的」,因爲它們是針對相同的用戶,相同的服務,甚至是在相同情況下(我認爲)獲得的。如果我做了一個toString(),我比較它們的輸出是一樣的(是的,我知道這是無關的,但它仍然是一個很好的跡象表明它們應該是相等的)。

但是,GSSCredential_1.equals(GSSCredential_2)總是在請求之間返回false。這可能是因爲每個票據都是使用不同的SPNEGO票據獲得的(爲了避免重放場景,這是必要的,但是這些票據仍然屬於同一個委託人,並「針對」相同的服務主體。

在代碼決定我需要這樣的最佳闡述:

做這些新憑證代表相同的安全主體如先前使用的呢?過期問題,有效性問題以及未分別評估的問題,以及以後的問題。

比較他們的名字「作品」,但我希望有一些更強大的東西。

任何想法?

+0

我不認爲你會比比較名稱更好。你有沒有可能會失敗的場景? – 2012-04-23 18:14:52

回答

0

據的Javadoc,GSSCredentials.equals方法如果

測試此GSSCredential是否相同的實體所提供的對象。這兩個憑證必須通過相同的機制獲得,並且必須提及同一個委託人。

使用equals方法應該就足夠了。 但是看執行顯示背後的怪異行爲的原因:

public boolean equals(Object another) { 

    if (destroyed) { 
     throw new IllegalStateException("This credential is " + 
            "no longer valid"); 
    } 

    if (this == another) { 
     return true; 
    } 

    if (!(another instanceof GSSCredentialImpl)) { 
     return false; 
    } 

    // NOTE: The specification does not define the criteria to compare 
    // credentials. 
    /* 
    * XXX 
    * The RFC says: "Tests if this GSSCredential refers to the same 
    * entity as the supplied object. The two credentials must be 
    * acquired over the same mechanisms and must refer to the same 
    * principal. Returns "true" if the two GSSCredentials refer to 
    * the same entity; "false" otherwise." 
    * 
    * Well, when do two credentials refer to the same principal? Do 
    * they need to have one GSSName in common for the different 
    * GSSName's that the credential elements return? Or do all 
    * GSSName's have to be in common when the names are exported with 
    * their respective mechanisms for the credential elements? 
    */ 
    return false; 
} 

這清楚地表明,你只能獲得真正的,當你提供完全相同的對象實例返回。 所以我想你需要比較GSSNameOid(機制)。