Rom*_*man 6 spring ldap spring-security spring-ldap
我想在本地缓存LDAP用户数据以允许更快的查询.Spring LDAP提供了这样的功能吗?我怎样才能做到这一点?
我使用Spring Security 3.1和Spring LDAP 1.3.1进行身份验证和授权.如果存在,使用内置机制为LDAP建立缓存会很好.
的applicationContext-ldap.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: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>
Run Code Online (Sandbox Code Playgroud)
弹簧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>
Run Code Online (Sandbox Code Playgroud)
非常感谢您的帮助!
我不认为 Spring 提供现成的客户端 LDAP 缓存,因为在客户端缓存 LDAP 查询结果会带来安全风险。缓存肯定会在某些时候保存过时的数据,如果它是用户的电子邮件/家庭地址,这并不是一个大问题,但当涉及到角色分配和其他身份验证/授权相关数据时,情况会更糟。通过扩展服务器端,使其能够处理负载,您的情况会好得多。
话虽这么说,从 Spring 3.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);
}
}
Run Code Online (Sandbox Code Playgroud)
包装类只是将所有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);
}
...
}
Run Code Online (Sandbox Code Playgroud)
有关如何配置 Spring 使用的缓存存储的详细信息,请参阅官方文档和本教程。
但我再次强调,你最好不要这样做。
| 归档时间: |
|
| 查看次数: |
5247 次 |
| 最近记录: |