본문 바로가기

프로그래밍/JAVA 프로그래밍

자바에서 LDAP 사용하기

LDAP 이란


Lightweight Directory Access Protocol.

조직이나 개체, 네트웍상에 있는 파일이나 장치들과 같은 자원등의 위치를 찾을 수 있게 해주는 소프트웨어 프로토콜이다. 


LDAP은 DAP의 경량판으로 네트워크내의 디렉토리 서비스 표준인 X.500의 일부이다.

넷스케이프는 자신들의 커뮤니케이터 최신판에 LDAP을 포함하였고, 마이크로소프트는 액치브 디렉토리라고 부르는 제품의 일부로 LDAP을 포함하였다. 노벨 넷웨어 디렉토리 서비스는 LDAP과 상호운영되며, 시스코도 자사의 네트워킹 제품에서 LDAP을 지원하고 있다.



자바에서 LDAP 사용하기



자바는 LDAP에 저장된 데이터를 액세스 하기위한 훌륭한 프레임웍을 제공한다.


LDAP에 연결하기 위해 JNDI(Java Naming and Directory Interface)을 사용하며 다음 4개 클래스 정도가 주로 많이 사용된다.


  1. javax.naming.directory.InitialDirContext
    • 디렉토리 서비스의 Base 가 되는 클래스 이다. 좀 더 이해하기 쉽게 말하면, JDBC의 Connection 인터페이스와 같은 역할을 한다. LDAP 통신을 하기위한 Host 정보나 인증 절차를 위한 계정, 비밀번호와 같은 것들을 설정하여 해당 디렉토리 서버와의 연결을 만들어내는 역할을 한다.

  2. javax.naming.directory.SearchControls
    • 생성된 Context 를 통해서 LDAP 경로 및 필터 문자열을 통해 개체 정보를 검색하는 역할을 한다.

  3. javax.naming.directory.SearchResult
    • 검색된 결과 개체의 데이터 유형이다. 해당 클래스의 getAttributes() 메소드를 이용하여 해당 개체의 정보들을 추출해 낼 수 있다.

  4. javax.naming.directory.Attribute
    • 이는 AD의 개체의 특정 항목 정보를 담고 있다.


LDAP 접속정보는 Properties 객체를 사용하여 설정한다.


Hashtable<String, String> properties = new Hashtable<String, String>();

properties.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");

properties.put(Context.PROVIDER_URL, path);

properties.put(Context.SECURITY_AUTHENTICATION, "simple");

properties.put(Context.SECURITY_PRINCIPAL, userId);

properties.put(Context.SECURITY_CREDENTIALS, passwd);



properties.put(Context.SECURITY_AUTHENTICATION, "simple"); 
// 여기는 simple 대신에 none 을 써주면 아래 userId 나 passwd 를 설정해주지 않아도 된다. 단 해당 LDAP 호스트에서 익명 조회가 가능하도록 설정 해 두었을때 이야기다.

properties.put(Context.SECURITY_PRINCIPAL, userId); 
// userId 값은 foo@mycompany 혹은 foo@ds.mycompany.com 형식을 사용한다.
// 패스워드 부분이 null 이거나 공백없는 문자열 ("") 일 경우에는 인증 과정이 이루어지지 않는다



LDAP 사용예

import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;

public class Test {
	private static String userId = "test";
	private static String passwd = "pass";
	private static String ldapDomain = "ds.mycompany.com";
	private static String ldapPathFormat = "LDAP://%s/";

	public static void main(String[] args) {
		String path = String.format(ldapPathFormat, ldapDomain);
		System.out.println(path);

		String filterString = "(cn=mrtint)";

		// LDAP Context
		DirContext context = null;

		// LDAP property 설정
		Hashtable properties = new Hashtable();
		properties.put(Context.INITIAL_CONTEXT_FACTORY,
				"com.sun.jndi.ldap.LdapCtxFactory");
		properties.put(Context.PROVIDER_URL, path);
		properties.put(Context.SECURITY_AUTHENTICATION, "simple");
		properties.put(Context.SECURITY_PRINCIPAL, userId);
		properties.put(Context.SECURITY_CREDENTIALS, passwd);

		try {
			context = new InitialDirContext(properties);
			SearchControls searcher = new SearchControls();
			// 
			searcher.setSearchScope(SearchControls.SUBTREE_SCOPE);
			NamingEnumeration results = context.search(
					"OU=Employee,DC=ds,DC=mycompany,DC=com", filterString, searcher);
			while (results.hasMore()) {
				SearchResult result = results.next();
				Attributes attrs = result.getAttributes();
				System.out.println(attrs.get("displayName"));
			}
		} catch (NamingException e) {
			e.printStackTrace();
		}

		System.out.println(isAuthenticatedUser("mrtint@ds.mycompany.com",
				"test123"));

	}


	public static boolean isAuthenticatedUser(String userId, String password) {
		boolean isAuthenticated = false;
		String path = String.format(ldapPathFormat, ldapDomain);
		if (password != null && password != "") {
			Hashtable properties = new Hashtable();
			properties.put(Context.INITIAL_CONTEXT_FACTORY,
					"com.sun.jndi.ldap.LdapCtxFactory");
			properties.put(Context.PROVIDER_URL, path);
			properties.put(Context.SECURITY_AUTHENTICATION, "simple");
			properties.put(Context.SECURITY_PRINCIPAL, userId);
			properties.put(Context.SECURITY_CREDENTIALS, password);
			try {
				DirContext con = new InitialDirContext(properties);
				isAuthenticated = true;
				con.close();
			} catch (NamingException e) {
			}
		}
		return isAuthenticated;
	}
}