【问题标题】:Could not connect to Active Directory services through LDAP in JAVA无法在 JAVA 中通过 LDAP 连接到 Active Directory 服务
【发布时间】:2016-11-21 08:11:48
【问题描述】:

我是 LDAP 和 Active Directory 的新手。我刚刚在 Windows Server 2012 中安装了与 Active Directory 相关的功能,并且所有配置都已完成并创建了一个用户。

当我尝试通过 LDAP 连接 Active Directory 时,出现以下错误。

Exception in thread "main" javax.naming.AuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C0903C5, comment: AcceptSecurityContext error, data 52e, v2580]
at com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:3067)
at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:3013)
at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2815)
at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2729)
at com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:296)
at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:175)
at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:193)
at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:136)
at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:66)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:667)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)
at javax.naming.InitialContext.init(InitialContext.java:223)
at javax.naming.ldap.InitialLdapContext.<init>(InitialLdapContext.java:134)
at com.infomindz.sample.ldap.LDAPTest.main(LDAPTest.java:79)

我尝试了在线文章中给出的一些解决方案,但仍然遇到相同的错误,并且不知道如何解决此类异常。仅使用以下代码我尝试过

public static void main(String[] args) throws NamingException
{

    final String ldapSearchBase = "dc=sample,dc=com";

    final String ldapUsername = "sampleAdminUser";
    final String ldapPassword = "password";

    final String ldapAccountToLookup = "sampleUser";


    Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.PROVIDER_URL, "ldap://XX.XX.XX.XX:389");
    env.put(Context.SECURITY_AUTHENTICATION, "simple");
    if(ldapUsername != null)
    {
        env.put(Context.SECURITY_PRINCIPAL, ldapUsername);
    }
    if(ldapPassword != null)
    {
        env.put(Context.SECURITY_CREDENTIALS, ldapPassword);
    }

    LdapContext ctx1 = new InitialLdapContext(env, null);
    LDAPTest ldap = new LDAPTest();

    SearchResult srLdapUser = ldap.findAccountByAccountName(ctx1, ldapSearchBase, ldapAccountToLookup);

    System.out.println("srLdapUser :" + srLdapUser);

}

从我的以下代码行中的代码本身就遇到了错误:

LdapContext ctx1 = new InitialLdapContext(env, null);

如果我在这方面滞后,请发布您的上下文。 提前致谢。

【问题讨论】:

  • LDAP: error code 49 表示凭据无效。你确定它们是正确的吗?
  • @RobAu 是的,凭据都正确。为什么我对此有信心,因为我使用相同的用户名和密码登录系统。

标签: java ldap jndi ldap-query


【解决方案1】:

您需要将用户的 RDN 提供为 SECURITY_PRINCIPAL,例如“cn=Administrator”或完整的 DN,例如“cn=Administrator,ou=xyz,dc=infomindz,dc=com”。

要进行交叉检查,您可以安装 LDAP 浏览器,例如 Apache Directory Studio (https://directory.apache.org/studio/),然后尝试连接到提供 RDN 或管理员用户 DN 的 AD。

【讨论】:

  • 我认为你不需要 Microsoft AD。
  • @RobAu 我认为 JNDI 需要它,无论您连接到哪个 LDAP 服务器。
  • Microsoft Active Directory 有一个 LDAP 服务器端功能的概念,称为模糊名称解析 (ldapwiki.com/wiki/Ambiguous%20Name%20Resolution),它允许使用一些高级绑定值。
  • @jwilleke 我是正确的。感谢 RobAu 和 jwilleke 教授新知识。
【解决方案2】:

通过以下更新的代码,我使用 LDAP Query

Active Directory 获取用户和用户的详细信息来实现

ldapUsername域控制器 的管理员用户。

ldapPassword是管理员用户的密码。

ldapAccountToLookup 是必须在给定域下搜索的用户名。

public static void main(String[] args) throws NamingException
{

    final String ldapSearchBase = "dc=NewForest,dc=sample,dc=com";

    final String ldapUsername = "sampleAdminUser";
    final String ldapPassword = "Password";

    final String ldapAccountToLookup = "sampleUser";


    Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.PROVIDER_URL, "ldap://XX.XX.XX.XX:389");
    env.put(Context.SECURITY_AUTHENTICATION, "simple");
    env.put(Context.SECURITY_PRINCIPAL, ldapUsername);
    env.put(Context.SECURITY_CREDENTIALS, ldapPassword);
    DirContext ctx = new InitialDirContext(env);


    LDAPTest ldap = new LDAPTest();

    SearchResult srLdapUser = ldap.findAccountByAccountName(ctx, ldapSearchBase, ldapAccountToLookup);
    System.out.println("srLdapUser :" + srLdapUser);

}

【讨论】:

    猜你喜欢
    • 2013-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-19
    • 2021-03-17
    • 2010-09-26
    • 2020-07-02
    • 1970-01-01
    相关资源
    最近更新 更多