Java GSSAPI:比较两个GSSCredential实例

时间:2012-04-23 17:38:16

标签: java kerberos spnego gssapi

我的代码目前可以很好地为我的网站用户执行SPNEGO(Kerberos)身份验证。我有一个特殊的缓存机制,可以根据用户身份的确认来加速某些决策。对于普通密码验证,这很简单 - 将“当前”用户+密码组合与“旧”密码组合进行比较 - 如果没有变化,仍然可以缓存决策。否则,他们需要重新评估。

我正在尝试为Kerberos做同样的事情。我已经完成了大部分工作,但我很困惑为什么GSSCredential.equals()不能正常工作。特别是,我在验证每个请求后获得的GSSCredential实例是“相同的”,因为它们是针对相同的用户,相同的服务,甚至在相同的情况下获得(我认为)。如果我做toString()并且我比较输出它们是相同的(是的,我知道这是无关紧要的,但它仍然是一个很好的迹象表明它们可能应该相等)。

但是,GSSCredential_1.equals(GSSCredential_2)始终在请求之间返回false。这可能是因为每个都是使用不同的SPNEGO票证获得的(根据Kerberos,这是必要的,以避免重放场景),但这些票证仍然属于同一主体并且“瞄准”同一服务主体。

我需要做出的代码决策最好明确表达:

这些新凭据是否代表与之前使用的相同的安全主体?到期问题,目的有效性以及未分别评估的问题,以及稍后的评估。

比较他们的名字“作品”,但我希望有更强大的东西。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

根据GSSCredentials.equals方法的javadocs

  

测试此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;
}

这清楚地表明,只有在提供完全相同的对象实例时,才会返回true。 所以我想你需要比较GSSNameOid(机制)。