LDAP

 

 

Ldap

 

1.   简介

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

 

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 – suer name(真实名称)

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 distinguished names。表示相对于顶点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中得到。

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

    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;


    private final
String FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";
    private
LdapContext ctx = null;
    private final
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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
校园悬赏任务平台对字典管理、论坛管理、任务资讯任务资讯公告管理、接取用户管理、任务管理、任务咨询管理、任务收藏管理、任务评价管理、任务订单管理、发布用户管理、管理员管理等进行集中化处理。经过前面自己查阅的网络知识,加上自己在学校课堂上学习的知识,决定开发系统选择小程序模式这种高效率的模式完成系统功能开发。这种模式让操作员基于浏览器的方式进行网站访问,采用的主流的Java语言这种面向对象的语言进行校园悬赏任务平台程序的开发,在数据库的选择上面,选择功能强大的Mysql数据库进行数据的存放操作。校园悬赏任务平台的开发让用户查看任务信息变得容易,让管理员高效管理任务信息。 校园悬赏任务平台具有管理员角色,用户角色,这几个操作权限。 校园悬赏任务平台针对管理员设置的功能有:添加并管理各种类型信息,管理用户账户信息,管理任务信息,管理任务资讯公告信息等内容。 校园悬赏任务平台针对用户设置的功能有:查看并修改个人信息,查看任务信息,查看任务资讯公告信息等内容。 系统登录功能是程序必不可少的功能,在登录页面必填的数据有两项,一项就是账号,另一项数据就是密码,当管理员正确填写并提交这二者数据之后,管理员就可以进入系统后台功能操作区。项目管理页面提供的功能操作有:查看任务,删除任务操作,新增任务操作,修改任务操作。任务资讯公告信息管理页面提供的功能操作有:新增任务资讯公告,修改任务资讯公告,删除任务资讯公告操作。任务资讯公告类型管理页面显示所有任务资讯公告类型,在此页面既可以让管理员添加新的任务资讯公告信息类型,也能对已有的任务资讯公告类型信息执行编辑更新,失效的任务资讯公告类型信息也能让管理员快速删除。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值