我已将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
,但是当第一个auth提供程序对用户进行身份验证时,Spring不使用第二个提供程序。只有当第一个身份验证提供程序无法对其进行身份验证时,才会在列表中接下来。
所以基本上看起来我们必须自定义
<security:ldap-authentication-provider user-dn-pattern="uid={0}" />
从本地数据库加载ROLE。
有什么建议吗?该如何实施?
答案 0 :(得分:5)
身份验证提供程序必须在成功身份验证时提供完全填充的身份验证令牌,因此无法使用一个提供程序检查用户的凭据,而另一个提供程序则可以为其分配权限(角色)。
但是,您可以自定义ldap auth提供程序以从数据库获取用户角色而不是默认行为(在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
实现的简单包装器,应该在配置中的某处定义。