我尝试在我的 Spring MVC 应用程序中对用户进行身份验证。我的域内有一个 Active Directory 服务器,但我的 Web 服务器在域外,所以我不得不建立一个 OpenLDAP 代理服务器。
首先,我已成功尝试在我的域内建立连接,因此应用程序工作正常并进行身份验证。一切都好……但是
在阅读了数百个网站(因为新的 cn=conf 配置 - 而不是 slap.conf,这是 IMO 很难学习,因为大多数网站都描述了不推荐使用的配置)和论坛之后,我终于用 ldap 配置了代理服务器后端,因此它像代理一样工作。并非没有任何问题 - 它在调用 ldapsearch 后挂起,但仍然返回结果。
问题是我的 OpenLDAP 配置的 ldapsearch 不接受带有 user@domain.com 表示法的专有名称......只有可接受......日志文件说:
11 月 13 日 14:24:52 ip-10-0-0-121 slapd[19149]: conn=1001 op=0 do_bind 11 月 13 日 14:24:52 ip-10-0-0-121 slapd[19149]: > >> dnPrettyNormal:11 月 13 日 14:24:52 ip-10-0-0-121 slapd[19149]:conn=1001 op=0 do_bind:无效 dn (user@domain.com) 11 月 13 日 14:24:52 ip -10-0-0-121 slapd[19149]:send_ldap_result:conn=1001 op=0 p=3
所以 >>> dnPrettyNormal : 是不可接受的,而是从我的 spring 应用程序生成的......
我认为有两种解决方法:
- (由我推荐)设置 OpenLDAP 以接受带有“at”(@)字符的符号......
- 强制 Spring 应用程序发送格式...但是怎么做呢?
我的spring-security.xml:
<authentication-manager>
<authentication-provider ref="ldapActiveDirectoryAuthProvider" />
</authentication-manager>
<beans:bean id="ldapActiveDirectoryAuthProvider"
class="org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider">
<beans:constructor-arg value="domain.com" />
<beans:constructor-arg value="ldap://xx.xx.xx.xx:389/" /> <!--fake IP-->
<beans:property name="authoritiesMapper" ref="grantedAuthoritiesMapper" />
<beans:property name="useAuthenticationRequestCredentials"
value="true" />
<beans:property name="convertSubErrorCodesToExceptions"
value="true" />
</beans:bean>
<beans:bean id="grantedAuthoritiesMapper"
class="com.xxx.ActiveDirectoryGrantedAuthoritiesMapper" />
你能告诉我如何解决我的问题吗?
解决方案/更新:
我已经设法建立连接。现在我使用的是 LdapAuthenticationProvider 而不是 ActiveDirectoryLdapAuthenticationProvider。
<authentication-manager>
<authentication-provider ref='ldapProvider' />
</authentication-manager>
<!-- This bean points at the embedded directory server created by the ldap-server
element above -->
<beans:bean id="contextSource"
class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
<beans:constructor-arg value="ldap://xx.xx.xx.xx:389/dc=domain,dc=com" />
<beans:property name="baseEnvironmentProperties">
<beans:map>
<beans:entry key="java.naming.referral" value="ignore" />
</beans:map>
</beans:property>
<beans:property name="userDn"
value="CN=user,OU=group,dc=domain,dc=com" />
<beans:property name="password" value="secret" />
</beans:bean>
<beans:bean id="ldapProvider"
class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
<beans:constructor-arg>
<beans:bean
class="org.springframework.security.ldap.authentication.BindAuthenticator">
<beans:constructor-arg ref="contextSource" />
<beans:property name="userSearch">
<beans:bean id="userSearch"
class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<beans:constructor-arg index="0" value="" />
<beans:constructor-arg index="1"
value="(sAMAccountName={0})" />
<beans:constructor-arg index="2" ref="contextSource" />
<beans:property name="searchSubtree" value="true" />
</beans:bean>
</beans:property>
</beans:bean>
</beans:constructor-arg>
<beans:constructor-arg>
<beans:bean
class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
<beans:constructor-arg ref="contextSource" />
<beans:constructor-arg value="" />
<beans:property name="searchSubtree" value="true" />
<beans:property name="rolePrefix" value="ROLE_" />
<beans:property name="convertToUpperCase" value="true" />
<beans:property name="ignorePartialResultException"
value="true" />
</beans:bean>
</beans:constructor-arg>