3

我目前正在尝试使用 SourceForge 中的SPNEGO 库(服务器使用相同的库)将 Java 客户端实现到受 SPNEGO 保护的 Web 服务。我无法让它成功验证,我的请求总是以

HTTP/1.1 500 Failure unspecified at GSS-API level (Mechanism level: Checksum failed)

这类似于我从具有不适当主机名的浏览器访问 Web 服务时得到的症状,并且确实 Wireshark 中的一些调试显示客户端发送了错误的 SPN 与请求 - 我发送到service-test.client.com注册为 SPN并且在 DNS 中有A记录,但在 Windows 域中注册为server-1234.client.corp. 即使我将请求发送到http://service-test.client.com(请参阅匹配Host的标头),Java 请求票证的 SPN 是“内部”Windows 名称:

HTTP 请求的 Wireshark 解码

从 Chrome 或 IE 发送的相同内容具有匹配的Host标头和 SPN:

在此处输入图像描述

由于在我的代码或 SPNEGO 库中没有发生这种转换,我认为它一定是在 JRE 中发生的。我一直在研究 JGSS 源代码,但有点难以理解。谁能告诉我如何跳过这个翻译并获得正确 SPN 的票?

客户端代码:

SpnegoHttpURLConnection con = new SpnegoHttpURLConnection("spnego-client", user, password);
con.connect(new URL("http://service-test.client.com:8083/service"));
int rc = con.getResponseCode();
String msg = con.getResponseMessage();
4

1 回答 1

4

从上面的评论中总结:

重新检查您的 DNS。进行反向查找。大多数问题是由不正确的反向 DNS 条目引起的。

RFC2713中的第 85页可能会对您有所帮助并检查RFC4120并搜索“canon”。

当使用 GSS-API 构建基于主机的服务的 SPN 时,您必须使用目标机制规范化该名称。RFC 说

当解析对这种类型的名称的引用时,可以通过尝试 DNS 查找并使用返回的完全限定域名或使用“主机名”来规范化“主机名”(作为示例实施策略)如果 DNS 查找失败,则提供。规范化操作还将主机名映射为小写字符。

Kerberos 5 RFC 说:

服务器和传输时。因此,例如,不应依赖未受保护的 DNS 记录将主机别名映射到服务器的主名称,接受主名称作为要联系的一方,因为攻击者可以修改映射并冒充派对。

Kerberos 和基于 Kerberos 的协议的实现不得使用不安全的 DNS 查询来规范化服务主体名称的主机名组件(即,它们不得使用不安全的 DNS 查询将一个名称映射到另一个名称以确定主体名称的主机部分哪一个是用来交流的)。在没有安全名称服务的环境中,应用程序作者可以在将名称传递给安全机制之前将静态配置的域名附加到不合格的主机名,但他们不应做更多。安全名称服务设施(如果可用)可能会被信任用于主机名规范化,但 KDC 实现不应要求客户端的此类规范化。

实施说明:许多当前实施对提供的服务名称进行了一定程度的规范化,通常使用 DNS,即使它会产生安全问题。但是,对于服务名称是否折叠为小写或是否使用反向解析,实现之间没有一致性。为了最大限度地提高互操作性和安全性,应用程序应该提供安全机制,其名称是通过将用户输入的名称折叠为小写而不执行任何其他修改或规范化而产生的。

似乎 GSS-API impls 可能会规范化,但如果 DNS 不受信任,Kerberos 不应该这样做。所以这取决于。完成反向查找是非常自然的。这就是 Kerberos 验证主机名的方式。如果您正在运行 DNS 循环,这实际上是至关重要的。没有它,它将永远无法构建真正的 SPN。

虽然我真的会在 Kerberos 邮件列表中这样做。这是一个非常有趣的观点。

krb5_sname_to_principal我已经检查了 MIT Kerberos 实现,如果您检查以下源代码,那么实际上有一个方法可以做到这一点sn2princ.c

if (type == KRB5_NT_SRV_HST) {
        struct addrinfo *ai = NULL, hints;
        int err;
        char hnamebuf[NI_MAXHOST];

        /* Note that the old code would accept numeric addresses,
           and if the gethostbyaddr step could convert them to
           real hostnames, you could actually get reasonable
           results.  If the mapping failed, you'd get dotted
           triples as realm names.  *sigh*

           The latter has been fixed in hst_realm.c, but we should
           keep supporting numeric addresses if they do have
           hostnames associated.  */

        memset(&hints, 0, sizeof(hints));
        hints.ai_flags = AI_CANONNAME;
        err = getaddrinfo(hostname, 0, &hints, &ai);
        if (err) {
#ifdef DEBUG_REFERRALS
            printf("sname_to_princ: failed to canonicalize %s; using as-is", hostname);
#endif
        }
        remote_host = strdup((ai && ai->ai_canonname) ? ai->ai_canonname : hostname);
        if (!remote_host) {
            if(ai)
                freeaddrinfo(ai);
            return ENOMEM;
        }

        if ((!err) && maybe_use_reverse_dns(context, DEFAULT_RDNS_LOOKUP)) {
            /*
             * Do a reverse resolution to get the full name, just in
             * case there's some funny business going on.  If there
             * isn't an in-addr record, give up.
             */
            /* XXX: This is *so* bogus.  There are several cases where
               this won't get us the canonical name of the host, but
               this is what we've trained people to expect.  We'll
               probably fix it at some point, but let's try to
               preserve the current behavior and only shake things up
               once when it comes time to fix this lossage.  */
            err = getnameinfo(ai->ai_addr, ai->ai_addrlen,
                              hnamebuf, sizeof(hnamebuf), 0, 0, NI_NAMEREQD);
            freeaddrinfo(ai);
            if (err == 0) {
                free(remote_host);
                remote_host = strdup(hnamebuf);
                if (!remote_host)
                    return ENOMEM;
            }
        } else
            freeaddrinfo(ai);
    }

所以,我想我们必须通过邮件列表询问。

于 2012-09-03T18:29:02.660 回答