LdapCtx 不能转换为 DirContextAdapter

Ray*_*Jia 3 spring-security

我正在运行 Spring Security 3.2.9 RELEASE,尝试使用 SpringSecurityLdapTemplate 访问 AD,同时遇到了这个问题。

依赖项是 spring-security-ldap-3.2.9.RELEASE.jar spring-ldap-core-1.3.2.RELEASE.jar

问题详情如下: java.lang.ClassCastException: com.sun.jndi.ldap.LdapCtx cannot be cast to org.springframework.ldap.core.DirContextAdapter at org.springframework.security.ldap.SpringSecurityLdapTemplate.searchForSingleEntryInternal(SpringSecurityLdapTemplate.java: 219)

从代码

try {
        while (resultsEnum.hasMore()) {
            SearchResult searchResult = resultsEnum.next();
            DirContextAdapter dca = (DirContextAdapter) searchResult.getObject();
            Assert.notNull(dca, "No object returned by search, DirContext is not correctly configured");

            if (logger.isDebugEnabled()) {
                logger.debug("Found DN: " + dca.getDn());
            }
            results.add(dca);
        }
    } catch (PartialResultException e) {
        LdapUtils.closeEnumeration(resultsEnum);
        logger.info("Ignoring PartialResultException");
    }
Run Code Online (Sandbox Code Playgroud)

似乎它正在尝试将搜索结果强制转换为 DirContextAdapter,不知道为什么不能强制转换。

我所有的代码在 spring-security-3.1.0 Release 下运行良好,因为 3.1.0 使用不同的逻辑

 try {
        while (resultsEnum.hasMore()) {
            SearchResult searchResult = resultsEnum.next();
            // Work out the DN of the matched entry
            DistinguishedName dn = new DistinguishedName(new CompositeName(searchResult.getName()));

            if (base.length() > 0) {
                dn.prepend(searchBaseDn);
            }

            if (logger.isDebugEnabled()) {
                logger.debug("Found DN: " + dn);
            }
            results.add(new DirContextAdapter(searchResult.getAttributes(), dn, ctxBaseDn));
        }
    } catch (PartialResultException e) {
        LdapUtils.closeEnumeration(resultsEnum);
        logger.info("Ignoring PartialResultException");
    }
Run Code Online (Sandbox Code Playgroud)

如何解决这个问题?

Ray*_*Jia 5

想了想代码,终于找到了答案,我自定义了AuthenticationProvider,在spring security 3.2之后,创建DirContext时需要添加Context.OBJECT_FACTORIES

env.put(Context.PROVIDER_URL, bindUrl);
     env.put(Context.SECURITY_CREDENTIALS, password);
     env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
     env.put(Context.OBJECT_FACTORIES, DefaultDirObjectFactory.class.getName());
Run Code Online (Sandbox Code Playgroud)