Spring LdapAuthentication 和从本地数据库加载角色

Posted

技术标签:

【中文标题】Spring LdapAuthentication 和从本地数据库加载角色【英文标题】:Spring LdapAuthentication and Load roles from local database 【发布时间】:2013-05-04 08:58:29 【问题描述】:

我已将 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" />

从本地数据库加载角色。

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

【问题讨论】:

【参考方案1】:

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

但是,您可以自定义 ldap 身份验证提供程序以从数据库中获取用户角色,而不是默认行为(在 ldap 中搜索用户组)。 LdapAuthenticationProvider 注入了两种策略:一种自己执行身份验证(LdapAuthenticator),另一种获取用户权限(LdapAuthoritiesPopulator)。如果您提供从数据库加载角色的LdapAuthoritiesPopulator 实现,则可以满足您的要求。如果您已经有一个 UserDetailsService 处理数据库,您可以通过将其包装在 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 与命名空间配置创建的基本相同。 (注意引用 ldap 服务器的 contextSource 属性。)

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

【讨论】:

这绝对是我想要的。 有没有办法将userId添加到User。将 empId 从 ldap 映射到 User 对象中的 userId 属性。 这个问题似乎和原来的问题无关。如果你重新制定它并作为一个新问题发布可能会更好,因为目前只有我可以看到它(实际上),而其他用户可以给你更好的答案。无论如何,将用户属性从 ldap 映射到 DB 是绝对可能的,但这不是你会(可以)用 Spring Security 做的事情。

以上是关于Spring LdapAuthentication 和从本地数据库加载角色的主要内容,如果未能解决你的问题,请参考以下文章

ldap spring security http基本身份验证

Spring Security - LDAP 身份验证和数据库授权

Apex 4.2 LDAP 身份验证 - 锁定用户

Spring框架系列 - Spring和Spring框架组成

你了解Spring从Spring3到Spring5的变迁吗?

Spring全家桶笔记:Spring+Spring Boot+Spring Cloud+Spring MVC