使用自定义模式定义进行Spring Ldap单元测试

Aur*_*e77 6 java spring unit-testing ldap spring-ldap

我正在尝试使用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'
Run Code Online (Sandbox Code Playgroud)

如果我objectClass: myOb从ldif 发表评论,则测试失败并显示空值(未读取属性).

这是我的测试类:

@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` !
    }
}
Run Code Online (Sandbox Code Playgroud)

和我的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
Run Code Online (Sandbox Code Playgroud)

Dmi*_*sev 2

我不知道如何使用 Spring Ldap 来做到这一点...但我在单元测试中使用 Unboundid InMemoryDirectoryServer 。服务器的这种实现不限制任何自定义对象类/属性定义。如果您愿意,我可以在这里分享我的 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();
}
Run Code Online (Sandbox Code Playgroud)

}

你可以像这样使用这个规则

@ClassRule
public static final LdapServerRule LDAP_RULE =
        new LdapServerRule("dc=mmkauth", resourceFilePath("data.ldiff"));
Run Code Online (Sandbox Code Playgroud)

LDAP_RULE.getListenPort() 返回用于连接的实际端口,或者您可以将端口直接传递到构造函数中