这里有一个spring-security示例ldap-xml,它运行一个ldap服务器并导入一个LDIF文件进行测试:
[...]
<s:ldap-server ldif="classpath:users.ldif" port="33389"/>
<s:authentication-manager>
<s:ldap-authentication-provider
group-search-filter="member={0}"
group-search-base="ou=groups"
user-search-base="ou=people"
user-search-filter="uid={0}"
/>
<s:authentication-provider ref='secondLdapProvider' />
</s:authentication-manager>
[...]
[...]
dn: uid=rod,ou=people,dc=springframework,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: Rod Johnson
sn: Johnson
uid: rod
userPassword: koala
[...]
我需要修改这个工作示例,其中user-search-criteria基于sAMAccountName而不是uid。我修改users.ldif如下:
[...]
dn: cn=rod,ou=people,dc=springframework,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: Rod Johnson
sn: Johnson
sAMAccountName: rod
userPassword: koala
[...]
但是,在导入users.ldif:
时,apached会显示警告OID for name 'samaccountname' was not found within the OID registry
似乎我需要通过修改LDAP模式来添加这个新属性sAMAccountName。如何在ldap-xml示例中做到这一点?
在此gist example中,他们使用&#34; changetype:add&#34;修改架构。但是在users.ldif中添加此项会导致错误We cannot have entries when reading a file which already contains changes
。在gist示例中,他们提到更新运行ldifde
命令的模式。我应该如何修改ldap-xml项目来执行此操作?
我如何修改ldap-xml项目,以便我的users.ldif可以包含sAMAccountName属性?
答案 0 :(得分:10)
在users.ldif文件的开头添加以下内容(它是包含sAMAccountName的Microsoft架构的最小片段):
dn: cn=microsoft, ou=schema
objectclass: metaSchema
objectclass: top
cn: microsoft
dn: ou=attributetypes, cn=microsoft, ou=schema
objectclass: organizationalUnit
objectclass: top
ou: attributetypes
dn: m-oid=1.2.840.113556.1.4.221, ou=attributetypes, cn=microsoft, ou=schema
objectclass: metaAttributeType
objectclass: metaTop
objectclass: top
m-oid: 1.2.840.113556.1.4.221
m-name: sAMAccountName
m-equality: caseIgnoreMatch
m-syntax: 1.3.6.1.4.1.1466.115.121.1.15
m-singleValue: TRUE
dn: ou=objectclasses, cn=microsoft, ou=schema
objectclass: organizationalUnit
objectclass: top
ou: objectClasses
dn: m-oid=1.2.840.113556.1.5.6, ou=objectclasses, cn=microsoft, ou=schema
objectclass: metaObjectClass
objectclass: metaTop
objectclass: top
m-oid: 1.2.840.113556.1.5.6
m-name: securityPrincipal
m-supObjectClass: top
m-typeObjectClass: AUXILIARY
m-must: sAMAccountName
[rest of users.ldif]
现在将新的objectClass添加到人员条目:
[...]
dn: cn=rod,ou=people,dc=springframework,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
objectclass: securityPrincipal <--- new objectClass
cn: Rod Johnson
sn: Johnson
sAMAccountName: rod
userPassword: koala
[...]
新条目还不够。 ApacheDS中的&#39; Spring Security中的配置有disabled schema interceptor,因此默认情况下不会创建新的模式条目。我们可以通过创建修复此问题的BeanPostProcessor来打开它:
package com.example.test.spring;
import java.util.List;
import org.apache.directory.server.core.interceptor.Interceptor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.security.ldap.server.ApacheDSContainer;
import static org.springframework.util.CollectionUtils.isEmpty;
public class ApacheDSContainerConfigurer implements BeanPostProcessor {
private List<Interceptor> interceptors;
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof ApacheDSContainer){
ApacheDSContainer dsContainer = ((ApacheDSContainer) bean);
setInterceptorsIfPresent(dsContainer);
}
return bean;
}
private void setInterceptorsIfPresent(ApacheDSContainer container) {
if (!isEmpty(interceptors)) {
container.getService().setInterceptors(interceptors);
}
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
public void setInterceptors(List<Interceptor> interceptors) {
this.interceptors = interceptors;
}
}
我们必须在应用程序上下文中注册和配置bean:
<bean class="com.example.test.spring.ApacheDSContainerConfigurer">
<property name="interceptors">
<list>
<bean class="org.apache.directory.server.core.normalization.NormalizationInterceptor"/>
<bean class="org.apache.directory.server.core.authn.AuthenticationInterceptor"/>
<bean class="org.apache.directory.server.core.referral.ReferralInterceptor"/>
<!--<bean class="org.apache.directory.server.core.authz.AciAuthorizationInterceptor"/>-->
<!--<bean class="org.apache.directory.server.core.authz.DefaultAuthorizationInterceptor"/>-->
<bean class="org.apache.directory.server.core.exception.ExceptionInterceptor"/>
<!--<bean class="org.apache.directory.server.core.changelog.ChangeLogInterceptor"/>-->
<bean class="org.apache.directory.server.core.operational.OperationalAttributeInterceptor"/>
<bean class="org.apache.directory.server.core.schema.SchemaInterceptor"/>
<bean class="org.apache.directory.server.core.subtree.SubentryInterceptor"/>
<!--<bean class="org.apache.directory.server.core.collective.CollectiveAttributeInterceptor"/>-->
<!--<bean class="org.apache.directory.server.core.event.EventInterceptor"/>-->
<!--<bean class="org.apache.directory.server.core.trigger.TriggerInterceptor"/>-->
<!--<bean class="org.apache.directory.server.core.journal.JournalInterceptor"/>-->
</list>
</property>
</bean>
现在应该可以了。
答案 1 :(得分:2)
我也有同样的问题,并尝试了@Karol给出的解决方案,但它对我没有用。
我使用Spring Framework提供的LdapTemplate
来访问Ldap服务器。
问题在于嵌入式ldap服务器(在我的情况下是 ApacheDS )并不支持某些属性,如{ {1}}。作为测试解决方案,我在我的代码中使用属性文件配置了这些属性名称,并将属性名称替换为测试环境属性文件中ApacheDS嵌入式服务器中可用的名称。它就像一个魅力。
例如,在实际环境中,LdapTemplate的搜索基于sAMAccountName
属性,但在测试环境中,搜索使用sAMAccountName
属性进行搜索。