如何在SpringLDAP中添加LDAP缓存?
我想在本地缓存LDAP用户数据,以允许更快的查询。SpringLDAP提供了这样的功能吗?我该怎么做 我使用SpringSecurity3.1和SpringLDAP 1.3.1进行身份验证和授权。如果存在,最好使用内置机制为LDAP提供缓存 Spring LDAP配置: applicationContext-ldap.xml:如何在SpringLDAP中添加LDAP缓存?,spring,spring-security,ldap,spring-ldap,Spring,Spring Security,Ldap,Spring Ldap,我想在本地缓存LDAP用户数据,以允许更快的查询。SpringLDAP提供了这样的功能吗?我该怎么做 我使用SpringSecurity3.1和SpringLDAP 1.3.1进行身份验证和授权。如果存在,最好使用内置机制为LDAP提供缓存 Spring LDAP配置: applicationContext-ldap.xml: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframe
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee.xsd
">
<!-- Ldap -->
<jee:jndi-lookup id="ldapUrl" jndi-name="appName/ldapUrl" expected-type="java.lang.String" />
<jee:jndi-lookup id="ldapUser" jndi-name="appName/ldapUser" expected-type="java.lang.String" />
<jee:jndi-lookup id="ldapPassword" jndi-name="appName/ldapPassword" expected-type="java.lang.String" />
<!-- for authentication and search purpose -->
<bean id="ldapContextSource" class="org.springframework.ldap.core.support.LdapContextSource">
<property name="url" ref="ldapUrl" />
<property name="userDn" ref="ldapUser" />
<property name="password" ref="ldapPassword" />
<property name="pooled" value="true" />
</bean>
<bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
<property name="contextSource" ref="ldapContextSource" />
</bean>
<!-- for pagination search purpose -->
<bean id="dirContext" factory-bean="ldapContextSource" factory-method="getReadOnlyContext" scope="session"/>
<bean id="singleLdapContextSource" class="org.springframework.ldap.core.support.SingleContextSource" scope="session">
<constructor-arg ref="dirContext"/>
</bean>
<bean id="singleLdapTemplate" class="org.springframework.ldap.core.LdapTemplate" scope="session">
<property name="contextSource" ref="singleLdapContextSource" />
</bean>
</beans>
Spring安全配置:
spring-security.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<!-- This is where we configure Spring-Security -->
<security:http
auto-config="true"
use-expressions="true"
access-denied-page="/auth/denied"
>
<security:intercept-url pattern="/login" access="permitAll"/>
<security:intercept-url pattern="/app/admin" access="permitAll"/>
<security:intercept-url pattern="/app/common" access="hasRole('User')"/>
<security:intercept-url pattern="/viol/home" access="permitAll"/>
<security:intercept-url pattern="/app/users" access="permitAll"/>
<security:intercept-url pattern="/admin/edit/*" access="hasRole('Administrator')"/>
<security:form-login
login-page="/auth/login"
authentication-failure-url="/auth/loginFailure"
default-target-url="/auth/authorize"/>
<security:logout
invalidate-session="true"
logout-success-url="/auth/login"
logout-url="/logout"/>
</security:http>
<security:authentication-manager>
<security:ldap-authentication-provider
server-ref="ldapContextSource"
user-search-filter="(sAMAccountName={0})"
user-search-base="dc=myDomain,dc=com"
/>
</security:authentication-manager>
</beans>
非常感谢你的帮助 我认为Spring不提供现成的客户端LDAP缓存,因为在客户端缓存LDAP查询结果会带来安全风险。缓存一定会在某个时候保存过时的数据,如果是用户的电子邮件/家庭地址,这不是一个大问题,但当涉及角色分配和其他身份验证/授权相关数据时,情况会更糟。通过扩展服务器端,使其能够处理负载,您的境况会好得多 也就是说,从Spring3.1开始引入缓存非常容易,因为它提供了对缓存的极好支持。在您的情况下,使用如下自定义
LdapContextSource
就足够了:
public class CachingLdapContextSource extends AbstractContextSource {
@Override
protected DirContext getDirContextInstance(Hashtable environment)
throws NamingException
{
InitialLdapContext context = new InitialLdapContext(environment, null);
return new CachingDirContextWrapper(context);
}
}
包装器类只是将所有DirContext
方法委托给底层实现,并用@Cacheable
装饰要缓存的方法
class CachingDirContextWrapper implements DirContext {
private final DirContext delegate;
CachingDirContextWrapper(DirContext delegate) {
this.delegate = delegate;
}
@Override
@Cacheable(value = "search")
public NamingEnumeration<SearchResult> search(...)
{
return delegate.search(name, matchingAttributes, attributesToReturn);
}
...
}
类CachingDirContextWrapper实现DirContext{
私人代表;
CachingDirContextWrapper(DirContext委托){
this.delegate=委托;
}
@凌驾
@可缓存(value=“搜索”)
公共名称计算搜索(…)
{
return delegate.search(名称、匹配属性、属性返回);
}
...
}
有关如何配置Spring使用的缓存存储的详细信息,请参阅和
但我想,您最好还是不要这样做。如果您配置并使用缓存,则可以将其用作:
<authentication-manager>
<authentication-provider>
<ldap-user-service
user-search-filter="(sAMAccountName={0})" user-search-base="dc=myDomain,dc=com" cache-ref="userCache" />
</authentication-provider>
</authentication-manager>