Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 由于JDNI实现,SpringLDAP过于严格_Java_Spring_Ldap_Spring Ldap_Javax - Fatal编程技术网

Java 由于JDNI实现,SpringLDAP过于严格

Java 由于JDNI实现,SpringLDAP过于严格,java,spring,ldap,spring-ldap,javax,Java,Spring,Ldap,Spring Ldap,Javax,再见 我在SpringLDAP上遇到了一个相当奇怪的问题,本质上,它更像是一个JSNI问题,而不是Spring问题 问题是: 我有以下LDAP结构: dc=company、dc=com、dc=productname |-o=TESTORG1 ||-ou=用户组名 ||-ou=用户 ||ou=user1@TESTORG1 |-o=TESTORG2 ||-ou=用户/组/名称 ||-ou=用户 ||ou=user1@TESTORG2 因此,我可以使用LdapTemplate(给定槽形弹簧)巧妙地创

再见

我在SpringLDAP上遇到了一个相当奇怪的问题,本质上,它更像是一个JSNI问题,而不是Spring问题

问题是:

我有以下LDAP结构:

dc=company、dc=com、dc=productname
|-o=TESTORG1
||-ou=用户组名
||-ou=用户
||ou=user1@TESTORG1
|-o=TESTORG2
||-ou=用户/组/名称
||-ou=用户
||ou=user1@TESTORG2
因此,我可以使用LdapTemplate(给定槽形弹簧)巧妙地创建所有这些。然而,如果我尝试递归删除一个组织,我会遇到一些奇怪的问题

  @Test
  public void createSimpleOrganisationWithSpecialChars() throws NamingException {
    LdapOrganisation originalOrg = new LdapOrganisation("TESTORG2");
    LdapUserGroup userGroup = new LdapUserGroup("User/Group/Name");
    userGroup.addUser(new User("user1",originalOrg ));
    originalOrg.addUserGroup(userGroup);
    dataAccess.updateLdap(originalOrg);
    OrganisationDao org = new OrganisationDao(this.ldapTemplate);
    org.unbind(organisation,true);
  }
解除绑定的实施如下所示:

    public void unbind(LdapOrganisation organisation, boolean recursive) {
      if(organisation != null) {
        DirContextAdapter context = new DirContextAdapter(buildDn(organisation));
        mapToContext(organisation, context);
        ldapTemplate.unbind(context.getDn(), recursive);
      }
    }
现在,如果运行此代码,则会出现以下错误:

  org.springframework.ldap.InvalidNameException: Invalid name: "ou=User/Group/Name"; nested exception is javax.naming.InvalidNameException: Invalid name: "ou=User/Group/Name"

    at org.springframework.ldap.support.LdapUtils.convertLdapException(LdapUtils.java:136)
    at org.springframework.ldap.support.LdapUtils.newLdapName(LdapUtils.java:416)
    at org.springframework.ldap.core.LdapTemplate.deleteRecursively(LdapTemplate.java:1103)
    at org.springframework.ldap.core.LdapTemplate$25.executeWithContext(LdapTemplate.java:1074)
    at org.springframework.ldap.core.LdapTemplate.executeWithContext(LdapTemplate.java:817)
    at org.springframework.ldap.core.LdapTemplate.executeReadWrite(LdapTemplate.java:812)
    at org.springframework.ldap.core.LdapTemplate.doUnbindRecursively(LdapTemplate.java:1072)
    at org.springframework.ldap.core.LdapTemplate.unbind(LdapTemplate.java:1036)
    at net.thadir.dataservices.ldap.dao.OrganisationDao.unbind(OrganisationDao.java:108)
    at net.thadir.dataservices.ldapaccess.LdapDataAccessTest.cleanTest(LdapDataAccessTest.java:93)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:33)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
    at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:239)
    at org.junit.rules.RunRules.evaluate(RunRules.java:20)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
  Caused by: javax.naming.InvalidNameException: Invalid name: "ou=User/Group/Name"
    at javax.naming.ldap.Rfc2253Parser.parseAttrType(Rfc2253Parser.java:155)
    at javax.naming.ldap.Rfc2253Parser.doParse(Rfc2253Parser.java:108)
    at javax.naming.ldap.Rfc2253Parser.parseDn(Rfc2253Parser.java:70)
    at javax.naming.ldap.LdapName.parse(LdapName.java:785)
    at javax.naming.ldap.LdapName.<init>(LdapName.java:123)
    at org.springframework.ldap.support.LdapUtils.newLdapName(LdapUtils.java:414)
    ... 37 more
在UserGroupDao中:

  public void delete(LdapOrganisation ldapOrganisation, String ldapUserGroup) {
        ldapTemplate.unbind(buildDn(ldapOrganisation.getOrganisationShortname(), ldapUserGroup));
  }

  public void delete(LdapOrganisation ldapOrganisation) {
        for (LdapUserGroup userGroup : ldapOrganisation.getUserGroups()) {
              delete(ldapOrganisation,userGroup.getGroupName());
        }
  }
但这似乎不起作用,因为我仍然得到相同的堆栈跟踪(因此,尝试以相同的方式执行似乎不起作用)


我一直在阅读所有这些RFC规范,这些规范看起来都很旧。LDAP似乎允许这样做,只是因为Spring似乎在递归部分使用JDNI,所以我遇到了这个问题。对你认为会被损坏的部件进行预清理似乎也不起作用。因此,我很想听到一些关于如何解决这个问题的建议/想法。

最后,我不得不自己实现
org.springframework.ldap.core.LdapTemplate
,以解决以下问题:

package net.thadir.dataservices.ldap.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ldap.NamingException;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.LdapContextSource;

import javax.naming.Binding;
import javax.naming.Name;
import javax.naming.NamingEnumeration;
import javax.naming.directory.DirContext;
import javax.naming.ldap.LdapName;

public class FixedLdapTemplate extends LdapTemplate {
  private static final Logger LOGGER = LoggerFactory.getLogger(FixedLdapTemplate.class);

  public FixedLdapTemplate(LdapContextSource contextSource) {
    super(contextSource);
  }

  /**
   * Delete all subcontexts including the current one recursively.
   *
   * @param ctx The context to use for deleting.
   * @param name The starting point to delete recursively.
   * @throws NamingException if any error occurs
   */
  @Override
  protected void deleteRecursively(DirContext ctx, Name name) {
    NamingEnumeration enumeration = null;
    try {
      enumeration = ctx.listBindings(name);
      while (enumeration.hasMore()) {
        Binding binding = (Binding) enumeration.next();
        String bindingName = binding.getName();
        LdapName childName = org.springframework.ldap.support.LdapUtils.newLdapName(fixJDNIBug(bindingName));
        childName.addAll(0, name);
        deleteRecursively(ctx, childName);
      }
      ctx.unbind(name);
      LOGGER.debug("Entry {} deleted", name);
    }
    catch (javax.naming.NamingException e) {
      throw org.springframework.ldap.support.LdapUtils.convertLdapException(e);
    }
    finally {
      try {
        if (enumeration != null) {
          enumeration.close();
        }
      }
      catch (Exception e) {
        LOGGER.trace("Never mind this", e);
      }
    }
  }

  /**
   * Becouse somhow JDNI things that if you have a binding with some special characters it adds some extra " to the beginnin and the end. We have to remove it.
   *
   * @param bindingName
   * @return
   */
  private static String fixJDNIBug(String bindingName) {
    String result = bindingName;
    if(result.contains("/") && result.startsWith("\"") && result.endsWith("\"")) {
      result = result.substring(1,bindingName.length()-1);
    }
    return result;
  }
}

在过去的10年里,这个问题一直是JDNI的一部分,所以我希望它能在春天很快得到修复。因为很遗憾,我不得不为sutch扩展这些课程,这是一件小事。

JDNI?JSNI?JNDI?您列出的DIT是不可能的。在同一父项下不能有两次
o=TESTORG1
。它也不符合您的代码“JDNI paten”未定义。不清楚你在问什么。你在我身上的拼写错误过滤掉了真名。。修好了,谢谢。我说的是Spring使用了javax的LdapName,它使用Rfc2253对DN的witch进行验证,而witch只需要用于整个其他主题。cnname中的LDAP allouws/文件。
package net.thadir.dataservices.ldap.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ldap.NamingException;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.LdapContextSource;

import javax.naming.Binding;
import javax.naming.Name;
import javax.naming.NamingEnumeration;
import javax.naming.directory.DirContext;
import javax.naming.ldap.LdapName;

public class FixedLdapTemplate extends LdapTemplate {
  private static final Logger LOGGER = LoggerFactory.getLogger(FixedLdapTemplate.class);

  public FixedLdapTemplate(LdapContextSource contextSource) {
    super(contextSource);
  }

  /**
   * Delete all subcontexts including the current one recursively.
   *
   * @param ctx The context to use for deleting.
   * @param name The starting point to delete recursively.
   * @throws NamingException if any error occurs
   */
  @Override
  protected void deleteRecursively(DirContext ctx, Name name) {
    NamingEnumeration enumeration = null;
    try {
      enumeration = ctx.listBindings(name);
      while (enumeration.hasMore()) {
        Binding binding = (Binding) enumeration.next();
        String bindingName = binding.getName();
        LdapName childName = org.springframework.ldap.support.LdapUtils.newLdapName(fixJDNIBug(bindingName));
        childName.addAll(0, name);
        deleteRecursively(ctx, childName);
      }
      ctx.unbind(name);
      LOGGER.debug("Entry {} deleted", name);
    }
    catch (javax.naming.NamingException e) {
      throw org.springframework.ldap.support.LdapUtils.convertLdapException(e);
    }
    finally {
      try {
        if (enumeration != null) {
          enumeration.close();
        }
      }
      catch (Exception e) {
        LOGGER.trace("Never mind this", e);
      }
    }
  }

  /**
   * Becouse somhow JDNI things that if you have a binding with some special characters it adds some extra " to the beginnin and the end. We have to remove it.
   *
   * @param bindingName
   * @return
   */
  private static String fixJDNIBug(String bindingName) {
    String result = bindingName;
    if(result.contains("/") && result.startsWith("\"") && result.endsWith("\"")) {
      result = result.substring(1,bindingName.length()-1);
    }
    return result;
  }
}