我正在尝试使用单点登录解决方案,该解决方案之前曾与Novell eDirectory一起作为LDAP提供商使用。现在,我正在尝试使用OpenLDAP。在登录过程中,其中一个步骤是从LDAP中检索实际用户。这是由Spring-security完成的,但似乎有一个bug。
要获取用户,请调用LdapUserDetailsService#loadUserByUsername
。这使用预定义的LdapUserSearch
来查找具有给定用户名的用户。在我的例子中,配置看起来像这样:
base:ou=something,ou=somethingElse,dc=oh,dc=my,dc=god
filter:cn={0}
其中{0}
替换为实际用户名。到目前为止,这是有效的,并且以FilterBasedLdapUserSearch#searchForUser
返回的userdata的形式检索用户。但是,userdata不会在dn和base之间分开,因此它具有:
base: (empty)
dn:cn=someUsername,ou=something,ou=somethingElse,dc=oh,dc=my,dc=god
此userdata对象又用于检索用户的权限,因此尝试使用上面的基础进行另一次搜索,并将dn作为过滤器。但是,此查询失败,因为OpenLDAP不允许任何以空字符串作为基础的查询。
我试过3.1.3.RELEASE,3.1.7.RELEASE和3.2.7.RELEASE,都有同样的问题。
这是春季安全漏洞吗?或者我在这里做错了什么?
答案 0 :(得分:0)
通过远离定义ldap用户服务的“模板”方式来管理修复它:
在:
<sec:ldap-user-service id="ldapUserDetailsService"
server-ref="contextSource"
user-search-filter="${my.ldap.filter}"
user-search-base="${my.ldap.base}"
user-context-mapper-ref="myUserDetailsContextMapper"/>
后:
<bean id="userSearch"
class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<constructor-arg index="0" value="${my.ldap.base}"/>
<constructor-arg index="1" value="${my.ldap.filter}"/>
<constructor-arg index="2" ref="contextSource"/>
</bean>
<bean id="ldapAuthoritiesPopulator" class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
<constructor-arg ref="contextSource"/>
<constructor-arg value="${my.ldap.usersearch.base}"/>
<property name="groupSearchFilter" value="${my.group.filter}" />
<property name="groupRoleAttribute" value="${my.group.attribute}" />
<property name="searchSubtree" value="true" />
</bean>
<bean id="ldapUserDetailsService" class="org.springframework.security.ldap.userdetails.LdapUserDetailsService">
<constructor-arg ref="userSearch"/>
<constructor-arg ref="ldapAuthoritiesPopulator"/>
</bean>
不要问我这是如何工作的原因。