我正在尝试使用Spring Ldap设置嵌入式ldap进行单元测试。但是我需要为自定义objectClasses / attributes定义使用自定义模式。如何使用Spring Ldap测试(LdapTestUtils?)
进行配置实际上,如果我运行测试,则说明我的自定义objectClass“myOb”未在模式中定义,并显示以下消息:
org.springframework.ldap.UncategorizedLdapException: Failed to populate LDIF; nested exception is javax.naming.directory.NoSuchAttributeException: [LDAP: error code 16 - NO_SUCH_ATTRIBUTE: failed for Add Request :
...
: OID for name 'myOb' was not found within the OID registry]; remaining name 'cn=123456, ou=MyUser, o=company.com'
如果我从ldif评论objectClass: myOb
,则测试失败并显示空值(未读取属性)。
这是我的测试类:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = LdapConfiguration.class, loader = AnnotationConfigContextLoader.class)
public class LdapTest {
// Ldap port
private static final int LDAP_PORT = 18880;
// Base DN for test data
private static final LdapName baseName = LdapUtils.newLdapName("o=company.com");
@Autowired
LdapTemplate ldapTemplate;
@BeforeClass
public static void setupBeforeClass() {
LdapTestUtils.startEmbeddedServer(LDAP_PORT, baseName.toString(), "ldaptest");
// How to load schema definition ?
}
@AfterClass
public static void teardownAfterClass() throws Exception {
LdapTestUtils.shutdownEmbeddedServer();
}
@Before
public void setup() throws Exception {
LdapTestUtils.cleanAndSetup(ldapTemplate.getContextSource(), baseName, new ClassPathResource("ldap/test-users.ldif"));
}
@Test
public void testSearchLdap() throws Exception {
String myObId = ldapTemplate.lookup(LdapNameBuilder.newInstance("ou=MyUser, o=company.com").add("cn", "123456").build(), new AbstractContextMapper<String>() {
@Override
protected String doMapFromContext(DirContextOperations ctx) {
return ctx.getStringAttribute("myObId"); // custom type
}
});
Assert.assertNotNull(myObId); // myObId is null if I comment `objectClass: myOb` !
}
}
和我的ldif:
dn: ou=MyUser, o=company.com
ou: User
description: MyUser
objectClass: top
objectClass: organizationalunit
dn: cn=123456, ou=MyUser, o=company.com
objectClass: top
objectClass: person
objectClass: myOb
cn: 123456
sn: 823456
myObId: TEST
答案 0 :(得分:1)
我不知道如何用Spring Ldap做到这一点...... 但我在单元测试中使用Unboundid InMemoryDirectoryServer。服务器的此实现不限制任何自定义objectClasses / attributes定义。 如果你愿意,我可以在这里分享我的JUnitRule。该规则启动InMemory服务器并将ldiff加载到其中
更新:
public class LdapServerRule extends ExternalResource {
private static final Log LOG = LogFactory
.getLog(LdapServerRule.class);
public static final String DefaultDn = "cn=Directory Manager";
public static final String DefaultPassword = "password";
private String baseDn;
private String dn;
private String password;
private String lDiffPath;
private InMemoryDirectoryServer server;
private int listenPort;
public LdapServerRule(String baseDn, String lDiffPath) {
this(baseDn, lDiffPath, 0);
}
public LdapServerRule(String baseDn, String lDiffPath, int listenPort) {
this.lDiffPath = lDiffPath;
this.baseDn = baseDn;
this.dn = DefaultDn;
this.password = DefaultPassword;
this.listenPort = listenPort;
}
@Override
protected void before() {
start();
}
@Override
protected void after() {
stop();
}
public int getRunningPort() {
return getServer().getListenPort();
}
private void start() {
InMemoryDirectoryServerConfig config;
try {
LOG.info("LDAP server " + toString() + " starting...");
config = new InMemoryDirectoryServerConfig(getBaseDn());
config.addAdditionalBindCredentials(getDn(),
getPassword());
config.setSchema(null);
config.setListenerConfigs(
InMemoryListenerConfig.createLDAPConfig("LDAP", getListenPort()));
setServer(new InMemoryDirectoryServer(config));
getServer().importFromLDIF(true, getLDiffPath());
getServer().startListening();
LOG.info("LDAP server " + toString() + " started. Listen on port " + getServer().getListenPort());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private void stop() {
server.shutDown(true);
LOG.info("LDAP server " + toString() + " stopped");
}
public String getBaseDn() {
return baseDn;
}
public String getDn() {
return dn;
}
public String getPassword() {
return password;
}
public InMemoryDirectoryServer getServer() {
return server;
}
public void setServer(InMemoryDirectoryServer server) {
this.server = server;
}
public String getLDiffPath() {
return lDiffPath;
}
public int getListenPort() {
return listenPort;
}
@Override
public String toString() {
return com.google.common.base.Objects.toStringHelper(this)
.add("baseDn", baseDn)
.add("listenPort", listenPort)
.toString();
}
}
您可以像这样使用此规则
@ClassRule
public static final LdapServerRule LDAP_RULE =
new LdapServerRule("dc=mmkauth", resourceFilePath("data.ldiff"));
LDAP_RULE.getListenPort()返回连接的实际端口,或者您可以将端口直接传递给构造函数
答案 1 :(得分:1)
Spring Boot提供了两个属性来忽略模式或设置模式文件的路径:
spring.ldap.embedded.validation.enabled=true # Whether to enable LDAP schema validation.
spring.ldap.embedded.validation.schema= # Path to the custom schema.