我使用ldap spring security来验证用户身份。验证没问题。由于复杂的权限,我们创建了一个CustomLdapAuthoritiesPopulator,请参阅下面的程序。一切正常,但连接没有关闭。每个用户登录时都会在执行以下行时创建新连接
List<String> appGroupUsersList = ldapTemplate.search(query, new AppGroupUsersListContextMapper());
我从ldap获得权限后如何关闭连接?
public class CustomLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator {
private static final Logger logger = LoggerFactory.getLogger(CustomLdapAuthoritiesPopulator.class);
private final LdapTemplate ldapTemplate;
private String groupSearchBase;
public AblLdapAuthoritiesPopulator(ContextSource contextSource, String groupSearchBase) {
this.ldapTemplate = new LdapTemplate(contextSource);
this.groupSearchBase = groupSearchBase;
}
@Override
public final Collection<GrantedAuthority> getGrantedAuthorities(DirContextOperations user, String username) {
if (groupSearchBase == null) {
return new HashSet<GrantedAuthority>();
}
logger.debug("Getting authorities for user " + user.getNameInNamespace());
LdapQuery query = query().base(groupSearchBase)
.where("cn").is("UsersList")
.and("objectclass").is("groupOfUniqueNames")
.and("uniqueMember").is(user.getNameInNamespace());
logger.debug("query: " + query.toString());
List<String> appGroupUsersList = ldapTemplate.search(query, new AppGroupUsersListContextMapper());
logger.debug("appGroupUsersList: " + appGroupUsersList.toString());
if(appGroupUsersList.size() == 0) {
throw new BadCredentialsException("Unauthorized Access");
}
List<String[]> functionsList = new LinkedList<String[]>();
for (String appGroup : appGroupUsersList) {
query = query().base("ou="+appGroup+","+groupSearchBase)
.where("cn").is("FunctionsList");
List<String[]> appGroupFunctionsList = ldapTemplate.search(query, new AppGroupFunctionsListContextMapper());
functionsList.addAll(appGroupFunctionsList);
}
Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
for (String[] roles : functionsList) {
for (String role : roles) {
authorities.add(new SimpleGrantedAuthority(role));
}
}
logger.debug("authorities: " + authorities.size());
return authorities;
}
private static class AppGroupUsersListContextMapper extends AbstractContextMapper<String> {
public String doMapFromContext(DirContextOperations context) {
String usersList = null;
Name dn = context.getDn();
if (!dn.isEmpty()) {
if (dn.size() > 3) {
usersList = (dn.get(2).split("="))[1];
}
}
return usersList;
}
}
private static class AppGroupFunctionsListContextMapper extends AbstractContextMapper<String[]> {
public String[] doMapFromContext(DirContextOperations context) {
String[] functionNames = null;
String[] functionsList = context.getStringAttributes("uniqueMember");
if (functionsList != null) {
functionNames = new String[functionsList.length];
for (int i = 0; i < functionsList.length; i++) {
String[] attributes = functionsList[i].split(",");
for (int j = 0; j < attributes.length; j++) {
String[] keyValue = attributes[j].split("=");
if ("cn".equalsIgnoreCase(keyValue[0])) {
functionNames[i] = keyValue[1];
}
}
}
}
return functionNames;
}
}
}
答案 0 :(得分:0)
在DefaultSpringSecurityContextSource中添加 pooled = false 后,问题得以解决。以下是我在xml中的配置。
<bean class="org.springframework.security.ldap.DefaultSpringSecurityContextSource" id="contextSource">
<constructor-arg value="${ldap.url}"/>
<property name="pooled" value="false" />
<property name="userDn" value="${ldap.managerUser}"/>
<property name="password" value="${ldap.managerPassword}"/>
</bean>
<ldap:ldap-template id="ldapTemplate" ignore-name-not-found="true" context-source-ref="contextSource"/>
<authentication-manager alias="authenticationManager">
<authentication-provider ref="customLdapAuthProvider"/>
</authentication-manager>
<beans:bean class="com.xxx.web.security.CustomLdapAuthenticationProvider" id="customLdapAuthProvider"/>
<beans:bean class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider" id="ldapAuthProvider">
<beans:constructor-arg ref="ldapBindAuthenticator"/>
<beans:constructor-arg ref="LdapAuthoritiesPopulator"/>
<beans:property name="userDetailsContextMapper" ref="ldapUserDetailsContextMapper"/>
</beans:bean>
<beans:bean class="com.xxx.web.security.CustomBindAuthenticator" id="ldapBindAuthenticator">
<beans:constructor-arg ref="contextSource"/>
<beans:property name="userSearch" ref="ldapSearchBean"/>
</beans:bean>
<beans:bean class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch" id="ldapSearchBean">
<beans:constructor-arg value="${ldap.userSearchBase}"/>
<beans:constructor-arg value="${ldap.userAttribute}"/>
<beans:constructor-arg ref="contextSource"/>
</beans:bean>
<beans:bean class="com.xxx.web.security.CustomLdapAuthoritiesPopulator" id="LdapAuthoritiesPopulator">
<beans:constructor-arg ref="contextSource" />
<beans:constructor-arg value="${ldap.groupSearchBase}"/>
</beans:bean>