LDAP

来源:互联网 发布:java rest请求xml 编辑:程序博客网 时间:2024/05/17 06:04

 

 

Ldap

 

1.  简介

LDAP(轻量级目录访问协议,Lightweight Directory AccessProtocol)是实现提供被称为目录服务的信息服务。

 

LDAP的信息是以树型结构存储的,在树根一般定义国家(c=CN)或域名(dc=com),在其下则往往定义一个或多个组织(organization)(o=Acme)或组织单元(organizational units)(ou=People)。一个组织单元可能包含诸如所有雇员、大楼内的所有打印机等信息。此外,LDAP支持对条目能够和必须支持哪些属性进行控制,这是有一个特殊的称为对象类别(objectClass)的属性来实现的。该属性的值决定了该条目必须遵循的一些规则,其规定了该条目能够及至少应该包含哪些属性。例如:inetorgPerson对象类需要支持sn(surname)cn(common name)属性,但也可以包含可选的如邮件,电话号码等属性。

 

2. 结构

2.1 LDAP简称对应

o–organization(组织-公司)

ou –organization unit(组织单元-部门)

c -countryName(国家)

dc -domainComponent(域名)

sn – suername(真实名称)

cn -common name(常用名称)

2.2 目录设计例子

设计目录结构是LDAP最重要的方面之一。下面我们将通过一个简单的例子来说明如何设计合理的目录结构。该例子将通过Netscape地址薄来访文。假设有一个位于美国US(c=US)而且跨越多个州的名为Acme(o=Acme)的公司。Acme希望为所有的雇员实现一个小型的地址薄服务器。

 

  我们从一个简单的组织DN开始: 

    dn: o=Acme,c=US

 

  Acme所有的组织分类和属性将存储在该DN之下,这个DN在该存储在该服务器的目录是唯一的。Acme希望将其雇员的信息分为两类:管理者(ou= Managers)和普通雇员(ou=Employees),这种分类产生的相对区别名(RDN,relative distinguishednames。表示相对于顶点DN)shi

 

    dn: ou=Managers,o=Acme, c=US

    dn: ou=Employees,o=Acme, c=US

 

  在下面我们将会看到分层结构的组成:顶点是USAcme,下面是管理者组织单元和雇员组织单元。因此包括ManagersEmployeesDN组成为:

    dn: cn=Jason H.Smith, ou=Managers, o=Acme, c=US

    dn: cn=Ray D. Jones,ou=Employees, o=Acme, c=US

    dn: cn=Eric S.Woods, ou=Employees, o=Acme, c=US

 

下面的实例保存目录信息数据为testdate.ldif文件,该文件的格式说明将可以在man ldif中得到。

  在添加任何组织单元以前,必须首先定义AcmeDN: 

    dn: o=Acme,c=US

    objectClass:organization

 

  这里o属性是必须的

    o: Acme

 

  下面是管理组单元的DN,在添加任何管理者信息以前,必须先定义该条目。

    dn: ou=Managers,o=Acme, c=US

    objectClass:organizationalUnit

这里ou属性是必须的。

 

ou:Managers

  第一个管理者DN

    dn: cn=Jason H.Smith, ou=Managers, o=Acme, c=US

    objectClass:inetOrgPerson

  cnsn都是必须的属性:

    cn: Jason H.Smith

    sn: Smith

  但是还可以定义一些可选的属性:

    telephoneNumber:111-222-9999

    mail:headhauncho@acme.com

    localityName: Houston

 

  可以定义另外一个组织单元:

    dn: ou=Employees,o=Acme, c=US

    objectClass:organizationalUnit

    ou:Employees

 

  并添加雇员信息如下:

    dn: cn=Ray D. Jones,ou=Employees, o=Acme, c=US

    objectClass:inetOrgPerson

    cn: Ray D.Jones

    sn: Jones

    telephoneNumber:444-555-6767

    mail:jonesrd@acme.com

    localityName: Houston

    dn: cn=Eric S.Woods, ou=Employees, o=Acme, c=US

    objectClass:inetOrgPerson

    cn: Eric S.Woods

    sn: Woods

    telephoneNumber:444-555-6768

    mail:woodses@acme.com

    localityName: Houston

 

3.使用LDAP认证例子

这里使用LDAP进行认证。

import org.springframework.core.io.FileSystemResource;
import
org.springframework.core.io.Resource;
import
org.springframework.core.io.support.PropertiesLoaderUtils;

import
javax.naming.AuthenticationException;
import
javax.naming.Context;
import
javax.naming.NamingEnumeration;
import
javax.naming.NamingException;
import
javax.naming.directory.SearchControls;
import
javax.naming.directory.SearchResult;
import
javax.naming.ldap.Control;
import
javax.naming.ldap.InitialLdapContext;
import
javax.naming.ldap.LdapContext;
import
java.net.URLDecoder;
import
java.util.Arrays;
import
java.util.Hashtable;
import
java.util.Properties;

public class
LdapImpl implements LdapApi {
   private String url;
   private
String baseDN;
   private
String defaultUser;
   private
String defaultPasswd;


    privatefinal
String FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";
   private
LdapContext ctx = null;
    privatefinal
Control[] connCtls = null;

   

   
private void connect() {
       Hashtable, String> env = new Hashtable, String>();
       
env.put(Context.INITIAL_CONTEXT_FACTORY, FACTORY);
       
env.put(Context.PROVIDER_URL, url + baseDN);
       
env.put(Context.SECURITY_AUTHENTICATION, "simple");

       

       String root = "cn=manager,dc=xxxxx,dc=com" // 根据自己情况修改
       
env.put(Context.SECURITY_PRINCIPAL, defaultUser);
       
env.put(Context.SECURITY_CREDENTIALS, defaultPasswd);


       try
{
           
ctx = new InitialLdapContext(env, connCtls);
           
Log.info("[LDAP] 认证成功");

       
} catch (javax.naming.AuthenticationException e) {
           Log.info(
"[LDAP] 认证失败 " +Arrays.toString(e.getStackTrace()));
       
} catch (Exception e) {
           Log.info(
"[LDAP] 认证出错 " +Arrays.toString(e.getStackTrace()));
       
}
    }

   
private void close() {
       
if (ctx != null) {
           
try {
               
ctx.close();
           
} catch (NamingException e) {
               e.printStackTrace()
;
           
}
       }
    }

   

   
private String getUserDN(String uid) {
       String userDN =
"";
       try
{
           SearchControls constraints=
new SearchControls();
           
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
           
NamingEnumeration en = ctx.search("", "cn=" + uid, constraints);
           if
(en == null || !en.hasMoreElements()) {
               Log.info(
"[LDAP] " + "未找到该用户");
           
}

           
// maybe more than one element
           
while (en.hasMoreElements()) {
               Object obj = en.nextElement()
;
               if
(obj instanceof SearchResult) {
                   SearchResult si = (SearchResult) obj
;
                   
userDN +=si.getNameInNamespace();
               
} else {
                   Log.info(
"[LDAP] " + String.valueOf(obj));
               
}
           }
       }
catch (Exception e) {
           Log.info(
"[LDAP] " + "查找用户时产生异常。" +Arrays.toString(e.getStackTrace()));
       
}

       
return userDN;
   
}

   
public boolean authenticate(String userName, String password) {
       
boolean valid = false;
       
readPropertites();
       
connect();
       
String userDN =getUserDN(userName);

       try
{
           
ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, userDN);
           
ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
           
ctx.reconnect(connCtls);
           
Log.info("[LDAP] " + userDN + " 验证通过");
           
valid = true;
       
} catch (AuthenticationException e) {
           Log.info(
"[LDAP] " + userDN + " 验证失败" +Arrays.toString(e.getStackTrace()));
       
} catch (NamingException e) {
           Log.info(
"[LDAP] " + userDN + " 验证失败" +Arrays.toString(e.getStackTrace()));
       
} finally {
           close()
;
       
}

       
return valid;
   
}

   public static void main(String[] args) {
       LdapImpl ldap = new LdapImpl();

       if (ldap.authenticate("test", "123456") == true) {

           System.out.println("
该用户认证成功");

       }
    }

   
public void readPropertites() {
       
try {
           String path =
this.getClass().getResource("/").getPath() + "ldap.properties";
           
path =URLDecoder.decode(path, "utf-8");
           
Resource resource = new FileSystemResource(path);

           
Properties properties =PropertiesLoaderUtils.loadProperties(resource);
           
url = properties.getProperty("URL");
           
baseDN = properties.getProperty("BASEDN");
           
defaultUser = properties.getProperty("USER");
           
defaultPasswd = properties.getProperty("PASSWD");
       
} catch (Exception e) {
           Log.info(
"[LDAP]" +Arrays.toString(e.getStackTrace()));
       
}

    }
   
public static void main(String[] args) {
       LdapImpl ldap =
new LdapImpl();
       
ldap.readPropertites();

       if
(ldap.authenticate("test", "123456") == true) {

           System.
out.println("该用户认证成功");

       
}
    }

}

 

URL:ldap://1.2.3.4:389/
BASEDN:dc=xxxxx,dc=com
USER:cn=Manager,dc= xxxxx,dc=com
PASSWD:123456

 

0 0