java - LDAP 在使用 GSSAPI 的 Java 子领域/跨领域设置中创建 InitialLdapContext 失败

标签 java ldap kerberos gssapi

我有一个在 KERBOS.COM 机器上运行的服务器进程,它试图连接到 IN.KERBOS.COM(子领域)中的 LDAP 服务器以使用 GSSAPI 机制同步用户。

通过查看 GSSLLOGS 我们可以看到
它试图验证的 spn 属于 KERBOS.COM ldap/invr28ppqa36.in.kerbos.com@KERBOS.COM 这是让它选择 IN.KERBOS.COM 作为领域的任何方式吗?

默认领域必须是 krb5.conf 中的 KERBOS.COM。因此,将默认领域更改为 IN.KERBOS.COM 不是一种选择。

我也给了它完全合格的名字所以应该有一些方法告诉它使用 IN.KERBOS.COM 作为领域。

env.put(Context.PROVIDER_URL, String.format("ldap://%s:%d", host, port));

Subject subject = new Subject();
subject.getPrivateCredentials().add(credential);
InitialLdapContext object  = Subject.doAs(subject, new PrivilegedExceptionAction<InitialLdapContext>() {   
  public InitialLdapContext run() throws Exception {                                
    env.put(Context.SECURITY_AUTHENTICATION, "GSSAPI");
    return new InitialLdapContext(env, null);
} });

日志

Subject.doAs fails by throwing an exception (Intercept from Logs are given)
Found ticket for **sysadmin@IN.KERBOS.COM to go to krbtgt/IN.KERBOS.COM@IN.KERBOS.COM**  Credentials acquireServiceCreds: obtaining service creds for **ldap/invr28ppqa36.in.kerbos.com@KERBOS.COM**
Using builtin default etypes for default_tgs_enctypes
default etypes for default_tgs_enctypes: 17 16 23 1 3.
KrbException: Fail to create credential. (63) - No service creds
    at sun.security.krb5.internal.CredentialsUtil.acquireServiceCreds(CredentialsUtil.java:301)
    at sun.security.krb5.Credentials.acquireServiceCreds(Credentials.java:442)
    at sun.security.jgss.krb5.Krb5Context.initSecContext(Krb5Context.java:641)
    at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:248)
    at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:179)
    at com.sun.security.sasl.gsskerb.GssKrb5Client.evaluateChallenge(GssKrb5Client.java:193)
    at com.sun.jndi.ldap.sasl.LdapSasl.saslBind(LdapSasl.java:123)
    at com.sun.jndi.ldap.LdapClient.authenticate(LdapClient.java:232)
    at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2740)
    at com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:316)
    at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:193)
    at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:211)
    at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:154)
    at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:84)
    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
    at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:307)
    at javax.naming.InitialContext.init(InitialContext.java:242)
    at javax.naming.ldap.InitialLdapContext.<init>(InitialLdapContext.java:153)
    at (LDAPConnector.java:101)

最佳答案

默认情况下,Kerberos 实现将从客户端领域的 KDC 开始,希望 KDC 可以提供到服务领域的跨领域引用。因此,您在 EXAMPLE.COM 中有一张票,您将前往名为 server.subdomain.example.com 的主机。您的客户端应该转到 EXAMPLE.COM KDC。那个 KDC 可以说它知道如何给你一张服务票,或者可以给你一张特殊的推荐票以更接近该服务;在此示例中,您可能希望它为您提供一个 krbtgt/SUBDOMAIN.EXAMPLE.COM@EXAMPLE.COM 领域。这告诉您的客户端转到 subdomain.example.com KDC。

显然,您的 KERBOS.COM KDC 不知道您的 LDAP 服务器由 IN.KERBOS.COM 领域提供服务。解决问题的一种方法是修复 KDC。这将取决于您拥有的 KDC 软件。或者,您可以编辑您的 krb5.conf 并告诉您的客户 in.kerbos.com 下的所有内容都由 IN.KERBOS.COM KDC 提供。在您的 krb5.conf 中添加如下部分:

[domain_realm]
.in.kerbos.com = IN.KERBOS.COM

参见 this作为讨论 krb5.conf 的示例,包括 Java 中的 domain_realm 部分。参见 RFC 6806有关推荐工作方式的技术细节。

关于java - LDAP 在使用 GSSAPI 的 Java 子领域/跨领域设置中创建 InitialLdapContext 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19180833/

相关文章:

java - 合并调试资源失败

java - 使用不带数组的扫描仪从文本文件中删除重复数据 (Java)

java - Apache Solr 与 Hibernate-Java 或 Ms SQL Server

java - ActiveMQ jndi.properties java.naming.referral

java - 为什么使用 Atlassian Crowd

java - Helloworld 数据库 - android 与 sqlite 的连接

java - LDAP 服务器更新和事件通知

macos - Kerberos kinit 输入密码不提示

hadoop - Hortonworks Kerberos : KRBError: error code is 14

java - 在 tomcat 8 中,如何在 setenv.bat 中提供文件路径以从 java 类读取