Spring和Ldap整合详解

官方主页

Spring

Spring Ldap

概述

LDAP(Light Directory Access Portocol),它是基于X.500标准的轻量级目录访问协议。

目录是一个为查询、浏览和搜索而优化的数据库,它成树状结构组织数据,类似文件目录一样。

目录数据库和关系数据库不同,它有优异的读性能,但写性能差,并且没有事务处理、回滚等复杂功能,不适于存储修改频繁的数据。所以目录天生是用来查询的,就好象它的名字一样。

LDAP目录服务是由目录数据库和一套访问协议组成的系统。

Spring已经为我们对Ldap做了很好的封装,有ldapTemplate可以用,但是这里我们要介绍的是jldap,非官方的ldap工具。

Git地址:Gitee

项目地址:品茗IT-同步发布

品茗IT 提供在线支持:

一键快速构建Spring项目工具

一键快速构建SpringBoot项目工具

一键快速构建SpringCloud项目工具

一站式Springboot项目生成

开始搭建

依赖Jar包
<dependency>
	<groupId>com.novell.ldap</groupId>
	<artifactId>jldap</artifactId>
	<version>4.3</version>
</dependency>
Spring-ldap配置

在spring的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:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:p="http://www.springframework.org/schema/p" xmlns:cache="http://www.springframework.org/schema/cache"
	xsi:schemaLocation="
                    http://www.springframework.org/schema/beans
                    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
                    http://www.springframework.org/schema/tx 
                    http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
                    http://www.springframework.org/schema/aop 
                    http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
                    http://www.springframework.org/schema/context      
                    http://www.springframework.org/schema/context/spring-context-4.0.xsd
                    http://www.springframework.org/schema/cache 
                    http://www.springframework.org/schema/cache/spring-cache-4.0.xsd">

	<context:annotation-config />
	<context:component-scan base-package="com.cff.springwork">
	</context:component-scan>


	<bean id="annotationPropertyConfigurer"
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="locations">
			<list>
				<value>classpath:ldap.properties</value>
			</list>
		</property>
	</bean>

</beans>

这里的xml文件只是为了引入配置文件,当然也可以把service定义为bean,根据个人喜欢随意选择,我们用到了ldap.properties配置文件。

ldap.properties:

ldap.host=127.0.0.1
ldap.port=389
ldap.bindDn=cn=Manager,dc=visit,dc=com
ldap.passwd=cff
ldap.baseDn=dc=visit,dc=com
Ldap调用的service

我们可以编写一个完整的service,方便以后使用,这个service 调用了util类。 LdapService:

package com.cff.springwork.ldap.service;

import java.io.UnsupportedEncodingException;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.cff.springwork.ldap.util.LdapUtil;
import com.novell.ldap.LDAPAttribute;
import com.novell.ldap.LDAPAttributeSet;
import com.novell.ldap.LDAPConnection;
import com.novell.ldap.LDAPEntry;
import com.novell.ldap.LDAPException;
import com.novell.ldap.LDAPModification;

@Service
public class LdapService {
	@Value("${ldap.host}")
	private String ldapHost;
	@Value("${ldap.port}")
	private int ldapPort = 389;
	@Value("${ldap.bindDn}")
	private String ldapBindDN;
	@Value("${ldap.passwd}")
	private String ldapPassword;
	@Value("${ldap.baseDn}")
	private String ldapBaseDN;
	
	/**
	 * 
	 * @param userName
	 * @param passwd
	 * @return 0000 成功
	 * @throws UnsupportedEncodingException
	 * @throws LDAPException
	 */
	public String addUser(String userName,String passwd) throws UnsupportedEncodingException, LDAPException{
		String errorCode = "0000";
		LdapUtil ld = new LdapUtil(ldapHost,ldapPort, ldapBindDN, ldapPassword);
		LDAPConnection lc = ld.connect();
		String dn = genDN(userName);
		LDAPEntry le = ld.search(lc,dn);
		if(le != null){
			LDAPAttribute la = new LDAPAttribute("userPassword", passwd);
			LDAPModification lm = new LDAPModification(LDAPModification.REPLACE,la);
			ld.modify(lc, dn, lm);
		}else{
			LDAPAttributeSet attributeSet = new LDAPAttributeSet();
			attributeSet.add(new LDAPAttribute("objectclass", new String(
					"person")));
			attributeSet.add(new LDAPAttribute("cn", userName));
			attributeSet.add(new LDAPAttribute("sn", userName));
			attributeSet.add(new LDAPAttribute("userPassword", passwd));
			ld.add(lc, dn, attributeSet);
		}
		ld.close(lc);
		return errorCode;
	}
	
	/**
	 * 
	 * @param userName
	 * @return 0000 成功 0001不存在
	 * @throws UnsupportedEncodingException
	 * @throws LDAPException
	 */
	public String removeUser(String userName) throws UnsupportedEncodingException, LDAPException{
		String errorCode = "0000";
		LdapUtil ld = new LdapUtil(ldapHost,ldapPort, ldapBindDN, ldapPassword);
		LDAPConnection lc = ld.connect();
		String dn = genDN(userName);
		LDAPEntry le = ld.search(lc,dn);
		if(le != null){
			ld.remove(lc,dn);
		}else{
			errorCode = "0001";
		}
		ld.close(lc);
		return errorCode;
	}
	
	public String genDN(String userName){
		String dn = "cn=" + userName + "," + ldapBaseDN;
		return dn;
	}

	public String getLdapHost() {
		return ldapHost;
	}

	public void setLdapHost(String ldapHost) {
		this.ldapHost = ldapHost;
	}

	public int getLdapPort() {
		return ldapPort;
	}

	public void setLdapPort(int ldapPort) {
		this.ldapPort = ldapPort;
	}

	public String getLdapBindDN() {
		return ldapBindDN;
	}

	public void setLdapBindDN(String ldapBindDN) {
		this.ldapBindDN = ldapBindDN;
	}

	public String getLdapPassword() {
		return ldapPassword;
	}

	public void setLdapPassword(String ldapPassword) {
		this.ldapPassword = ldapPassword;
	}

	public String getLdapBaseDN() {
		return ldapBaseDN;
	}

	public void setLdapBaseDN(String ldapBaseDN) {
		this.ldapBaseDN = ldapBaseDN;
	}
}
package com.cff.springwork.ldap.util;


import java.io.UnsupportedEncodingException;
import com.novell.ldap.LDAPAttributeSet;
import com.novell.ldap.LDAPConnection;
import com.novell.ldap.LDAPEntry;
import com.novell.ldap.LDAPException;
import com.novell.ldap.LDAPModification;

public class LdapUtil {
	private String ldapHost;
	private int ldapPort = 389;
	private String ldapBindDN;
	private String ldapPassword;
	private int ldapVersion = LDAPConnection.LDAP_V3;
	
	public LdapUtil() {
		super();
	}
	public LdapUtil(String ldapHost, String ldapBindDN, String ldapPassword) {
		super();
		this.ldapHost = ldapHost;
		this.ldapBindDN = ldapBindDN;
		this.ldapPassword = ldapPassword;
	}
	public LdapUtil(String ldapHost, int port, String ldapBindDN, String ldapPassword) {
		super();
		this.ldapHost = ldapHost;
		this.ldapPort = port;
		this.ldapBindDN = ldapBindDN;
		this.ldapPassword = ldapPassword;
	}
	public LdapUtil(String ldapHost, int ldapPort, String ldapBindDN, String ldapPassword, int ldapVersion) {
		super();
		this.ldapHost = ldapHost;
		this.ldapPort = ldapPort;
		this.ldapBindDN = ldapBindDN;
		this.ldapPassword = ldapPassword;
		this.ldapVersion = ldapVersion;
	}
	
	public String getLdapHost() {
		return ldapHost;
	}
	public void setLdapHost(String ldapHost) {
		this.ldapHost = ldapHost;
	}
	public int getLdapPort() {
		return ldapPort;
	}
	public void setLdapPort(int ldapPort) {
		this.ldapPort = ldapPort;
	}
	public String getLdapBindDN() {
		return ldapBindDN;
	}
	public void setLdapBindDN(String ldapBindDN) {
		this.ldapBindDN = ldapBindDN;
	}
	public String getLdapPassword() {
		return ldapPassword;
	}
	public void setLdapPassword(String ldapPassword) {
		this.ldapPassword = ldapPassword;
	}
	public int getLdapVersion() {
		return ldapVersion;
	}
	public void setLdapVersion(int ldapVersion) {
		this.ldapVersion = ldapVersion;
	}
	/**
	 * 根据配置连接LDAP服务器
	 * @return LDAPConnection 
	 * @throws LDAPException 连接失败
	 * @throws UnsupportedEncodingException 密码格式错
	 */
	public LDAPConnection connect() throws LDAPException, UnsupportedEncodingException
	{ 
		LDAPConnection lc = new LDAPConnection();
		lc.connect(ldapHost, ldapPort);
		lc.bind(ldapVersion, ldapBindDN, ldapPassword.getBytes("UTF8"));
		return lc;
    }
	
	/**
	 * 根据dn查询该dn下条目
	 * @param dn 例:cn=15607110725,dc=my-domain,dc=com
	 * @return LDAPEntry
	 * @throws LDAPException 连接失败/查找失败
	 * @throws UnsupportedEncodingException 密码格式错
	 */
	public LDAPEntry search(String dn) throws LDAPException, UnsupportedEncodingException{
		LDAPConnection lc;
		LDAPEntry le = null;
		lc = connect();
		le = lc.read(dn);
		lc.disconnect();
		return le;
	}
	
	/**
	 * 根据dn查询指定连接下该dn下条目
	 * @param lc LDAPConnection
	 * @param dn 例:cn=15607110725,dc=my-domain,dc=com
	 * @return LDAPEntry
	 * @throws LDAPException 查找失败
	 */
	public LDAPEntry search(LDAPConnection lc, String dn) throws LDAPException{
		LDAPEntry le = null;
		le = lc.read(dn);
		return le;
	}
	
	/**
	 * 增加新条目/用户
	 * @param dn 例:cn=15607110725,dc=my-domain,dc=com
	 * @param attributeSet LDAPAttributeSet ldap属性集合
	 * @throws UnsupportedEncodingException  密码格式错
	 * @throws LDAPException 连接失败/添加失败
	 */
	public void add(String dn, LDAPAttributeSet attributeSet) throws UnsupportedEncodingException, LDAPException{
		LDAPConnection lc = connect();
		LDAPEntry newEntry = new LDAPEntry( dn, attributeSet);
		lc.add(newEntry);
		lc.disconnect();
	}
	
	/**
	 * 指定连接增加新条目/用户
	 * @param lc LDAPConnection
	 * @param dn 例:cn=15607110725,dc=my-domain,dc=com
	 * @param attributeSet LDAPAttributeSet ldap属性集合
	 * @throws LDAPException 添加失败
	 */
	public void add(LDAPConnection lc, String dn, LDAPAttributeSet attributeSet) throws LDAPException{
		LDAPEntry newEntry = new LDAPEntry( dn, attributeSet);
		lc.add(newEntry);
	}
	
	/**
	 * 指定连接增加新条目
	 * @param lc LDAPConnection
	 * @param newEntry LDAPEntry:ldap条目
	 * @throws LDAPException 添加失败
	 */
	public void add(LDAPConnection lc, LDAPEntry newEntry) throws LDAPException{
		lc.add(newEntry);
	}
	
	/**
	 * 删除指定连接下dn所有内容
	 * @param lc LDAPConnection
	 * @param dn 例:cn=15607110725,dc=my-domain,dc=com
	 * @throws LDAPException 删除失败
	 */
	public void remove(LDAPConnection lc, String dn) throws LDAPException{
		lc.delete(dn);
	}
	
	/**
	 * 删除指定dn所有内容
	 * @param dn 例:cn=15607110725,dc=my-domain,dc=com
	 * @throws LDAPException 查找失败/删除失败
	 * @throws UnsupportedEncodingException 密码格式错
	 */
	public void remove(String dn) throws LDAPException, UnsupportedEncodingException{
		LDAPConnection lc = connect();
		lc.delete(dn);
		lc.disconnect();
	}
	
	/**
	 * 修改指定dn下某属性
	 * @param lc LDAPConnection
	 * @param dn 例:cn=15607110725,dc=my-domain,dc=com
	 * @param mod LDAPModification 修改的属性
	 * @throws LDAPException 修改失败
	 */
	public void modify(LDAPConnection lc, String dn, LDAPModification mod) throws LDAPException{
		lc.modify(dn, mod);
	}
	
	/**
	 * 关闭连接
	 * @param lc LDAPConnection
	 * @throws LDAPException 
	 */
	public void close(LDAPConnection lc) throws LDAPException{
		if(lc.isConnected()){
			lc.disconnect();
		}
	}
}