5

我已将 Spring Security 配置为针对 LDAP 服务器进行身份验证。

<security:authentication-manager >
    <security:ldap-authentication-provider user-dn-pattern="uid={0}" />

</security:authentication-manager>

身份验证后,我想从本地数据库为同一用户加载角色。如何使用“ldap-authentication-provider”加载本地数据库角色?

如果我添加第二个身份验证提供程序,如下所示:

<security:authentication-manager >
    <security:ldap-authentication-provider user-dn-pattern="uid={0}" />
            <security:authentication-provider ref="daoAuthenticationProvider" />
</security:authentication-manager>

daoAuthenticationProvider添加,但当第一个身份验证提供程序对用户进行身份验证时,Spring 不使用第二个提供程序。仅当第一个身份验证提供程序无法进行身份验证时,它才会进入列表中的下一个。

所以基本上看起来我们必须自定义

<security:ldap-authentication-provider user-dn-pattern="uid={0}" />

从本地数据库加载角色。

有什么建议么?这应该如何实施?

4

1 回答 1

5

身份验证提供程序必须在成功进行身份验证时提供完全填充的身份验证令牌,因此不可能使用一个提供程序来检查用户的凭据,并使用另一个提供程序为其分配权限(角色)。

但是,您可以自定义 ldap 身份验证提供程序以从数据库中获取用户角色,而不是默认行为(在 ldap 中搜索用户组)。注入了LdapAuthenticationProvider两种策略:一种自己执行身份验证(LdapAuthenticator),另一种获取用户的权限(LdapAuthoritiesPopulator)。如果您提供LdapAuthoritiesPopulator从数据库加载角色的实现,则可以满足您的要求。如果您已经UserDetailsService对数据库进行了处理,则可以通过将其包装在 a 中UserDetailsServiceLdapAuthoritiesPopulator并将其注入到LdapAuthenticationProvider.

由于这种配置相当少见,安全 xml 命名空间不提供标签/属性来设置它,但原始 bean 配置并不太复杂。这是大纲:

1)我想你ldap-server的配置中有一个地方。分配和分配给它很重要id,这将允许我们稍后引用它。

<security:ldap-server url="..." id="ldapServer" .../>

2) 在本authentication-manager节中,您将只参考定制的提供者:

<security:authentication-manager>
    <security:authentication-provider ref="customLdapAuthProvider"/>
</security:authentication-manager>

3)现在,最重要的部分:

<bean id="customLdapAuthProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
    <constructor-arg name="authenticator">
        <bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
            <constructor-arg name="contextSource" ref="ldapServer"/>
            <property name="userDnPatterns">
                <list>
                    <value>uid={0}</value>
                </list>
            </property>
        </bean>
    </constructor-arg>
    <constructor-arg name="authoritiesPopulator">
        <bean class="org.springframework.security.ldap.authentication.UserDetailsServiceLdapAuthoritiesPopulator">
            <constructor-arg name="userService" ref="userService"/>
        </bean>
    </constructor-arg>
</bean>

authenticator与命名空间配置创建的基本相同。(注意contextSource引用 ldap 服务器的属性。)

authoritiesPopulator是一个围绕您的实现的简单包装器userService,它应该在您的配置中的某处定义。

于 2013-05-10T12:02:37.987 回答