再见,
我对 Spring-LDAP 有一个相当奇怪的问题,它本质上似乎更像是一个 JSNI 问题,而不是一个 Spring 问题。
问题:
我有以下 LDAP 结构:
dc=company,dc=com,dc=productname
|-o=TESTORG1
| |-ou=UserGroupName
| |-ou=users
| |-ou=user1@TESTORG1
|-o=TESTORG2
| |-ou=User/Group/Name
| |-ou=users
| |-ou=user1@TESTORG2
所以我可以通过 Spring 使用 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
现在,如果我只是在用户组上的测试中进行正常的取消绑定。没有真正的问题。但它实际上是一个问题。因为似乎 Spring 用于递归删除 JDNI 模式(这比 LDAP 允许的更严格)和正常的取消绑定。它完美地工作。
现在我真的想让我的递归工作开箱即用。我尝试使用以下代码删除组:
在 OrganisationDoa 中:
public void unbind(LdapOrganisation organisation, boolean recursive) {
if(organisation != null) {
UserGroupDao ugu = new UserGroupDao(ldapTemplate);
ugu.delete(organisation);
DirContextAdapter context = new DirContextAdapter(buildDn(organisation));
mapToContext(organisation, context);
ldapTemplate.unbind(context.getDn(), recursive);
}
}
在 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 用于我遇到此问题的递归部分。并且对您预计会损坏的部分进行预清理似乎也不起作用。所以我很想听听一些建议/想法如何解决这个问题。