【问题标题】:Java GSSAPI: Compare two GSSCredential InstancesJava GSSAPI:比较两个 GSSCredential 实例
【发布时间】:2012-04-23 17:38:16
【问题描述】:

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

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

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

我需要做出的代码决策最好这样表述:

这些新凭据是否代表与以前使用的相同的安全主体?到期、目的有效性和其他问题单独评估,然后再评估。

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

有什么想法吗?

【问题讨论】:

  • 我不认为你会比比较名字更好。您是否有可能失败的场景?

标签: java kerberos spnego gssapi


【解决方案1】:

根据 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(机制)。

【讨论】:

    猜你喜欢
    • 2014-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-30
    • 2016-03-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多