首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多用户OU和多址CNs的Spring认证

多用户OU和多址CNs的Spring认证
EN

Stack Overflow用户
提问于 2014-06-23 11:11:39
回答 2查看 6.2K关注 0票数 0

如何尽可能使用Security/LDAP解决以下LDAP身份验证问题。

  • 用户属于两个LDAP组织单位之一(ou):客户或员工
  • 用户属于三个访问组中的一个(cn - groups )或它们的子组(cn)。

所以基本上应该是:

  1. 在LDAP (客户机或雇员)中查找用户的DN
  2. 绑定用户以检查密码
  3. 逐个搜索所有三个访问组及其子组,以找到具有用户DN的唯一their属性。

我研究过各种教程和例子,但它们似乎都没有关联,我无法将它们结合起来。如果access组是一个组织单元,它会更容易,但它不是。

整个页面以及所有的servlet都应该支持身份验证。

问题有点具体,但希望对社区有用。任何想法或建议都是最受欢迎的。

我目前使用的代码是spring文档中的修改版本。

代码语言:javascript
复制
<bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter">
    <property name="rolePrefix" value=""></property>
</bean>
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
    <constructor-arg name="decisionVoters" ref="roleVoter" />
</bean>

<security:http authentication-manager-ref="ldap-auth" access-decision-manager-ref="accessDecisionManager">
    <security:intercept-url pattern="/site/**" access="LDAP-Access-Group" />
    <security:form-login 
        login-page="/login" 
        authentication-failure-url="/denied"
        username-parameter="username" 
        password-parameter="password"
        default-target-url="/site/main" />
    <security:logout 
        invalidate-session="true" 
        logout-success-url="/login" 
        logout-url="/j_spring_security_logout" />
    <security:access-denied-handler error-page="/denied" />
    <security:session-management invalid-session-url="/login">
        <security:concurrency-control max-sessions="1" expired-url="/login" />            
    </security:session-management>
</security:http>

<bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
    <constructor-arg value="ldap://server:389/o=company,c=com"/>
</bean>

<security:authentication-manager id="ldap-auth">            
    <security:authentication-provider ref="ldapAuthProvider" />
</security:authentication-manager>

<bean id="ldapAuthProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
<constructor-arg>
    <bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
        <constructor-arg ref="contextSource"/>
        <property name="userDnPatterns">
            <list>
                <value>uid={0},ou=Employees</value>
                <value>uid={0},ou=Clients</value>
            </list>
        </property>
    </bean>
</constructor-arg>
<constructor-arg>
    <bean class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
        <constructor-arg ref="contextSource"/>
        <constructor-arg value="ou=Access"/>
        <property name="searchSubtree" value="true"/>
        <property name="groupRoleAttribute" value="cn" />
    </bean>
</constructor-arg>
</bean>

上面的代码似乎没有返回权限。是否有方法将输出发送到调试控制台?无法读取LDAP日志。

另外,如果我注释掉了AuthoritiesPopulator,那么在检查安全标记(即<sec:authorize access="isAuthenticated()">logged in</sec:authorize> )时,身份验证似乎是有效的,但出于某种原因,拦截-url阻止我使用<security:intercept-url pattern="/site/**" access="isAuthenticated()" />进入站点。我不明白。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-06-30 12:47:52

似乎主要的问题是在DefaultLdapAuthoritiesPopulator中指定搜索基参数。在DefaultLdapAuthoritiesPopulator bean中将值更改为"“解决了问题,并开始返回用户权限。

代码语言:javascript
复制
<bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
    <constructor-arg value="ldap://server:389/o=company,c=com"/>
    <property name="anonymousReadOnly" value="true"/>
</bean>

<bean id="ldapAuthProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
    <constructor-arg>
        <bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
            <constructor-arg ref="contextSource"/>
            <property name="userDnPatterns">
                <list>
                    <value>uid={0},ou=Employees</value>
                    <value>uid={0},ou=Clients</value>
                </list>
            </property>         
        </bean>
    </constructor-arg>
    <constructor-arg>
        <bean class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
            <constructor-arg ref="contextSource"/>
            <constructor-arg value=""/>
            <property name="searchSubtree" value="true"/>
            <property name="groupRoleAttribute" value="cn"/>
            <property name="groupSearchFilter" value="uniquemember={0}"/>   
        </bean>
    </constructor-arg>
</bean>
票数 0
EN

Stack Overflow用户

发布于 2014-06-23 11:53:41

步骤1和步骤2是LDAP身份验证的实际默认设置。

关于步骤3:一些LDAP服务器维护组及其成员之间的互惠关系。因此,当用户被添加到组时,组上的member属性和用户上的memberOf属性都会被填充。这将简化事情,因为您可以检索用户的memberOf属性并找到您的组。

既然您是在查询组,我想这对您来说不是这样的。我的建议是,创建一个包含三个主要访问组及其子组的所需组的列表。根据所需的灵活性,您可能应该在那里应用一些缓存。

接下来,使用(&(objectClass=groupOfUniqueNames)(member=cn=youruser,ou=some,o=org))查询LDAP服务器中所有以用户为成员的组,只返回DN列表,不返回属性(出于性能原因)。

现在,您可以查看返回组的列表,并查看您想要的组是否在其中。

这种方法确保您在登录时只需要一个查询总数(假设您缓存组列表),而不是每个组一个查询。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24364435

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档