`
kayo
  • 浏览: 548031 次
  • 性别: Icon_minigender_1
  • 来自: 安徽
社区版块
存档分类
最新评论

LDAP 集成应用实例

阅读更多
我们部门有一个系统是专门用来记录大家的请假和加班的.这个系统有一套用户名和密码,我们员工每个人都有一个公司统一分配的ID和密码.大家都觉得既然有统一的ID和密码,为什么还要多记一套登录口令呢?能不能试着把它们的验证系统统一起来,只用Intranet ID 和密码登录就行呢?
        我接到这个任务之后,就开始着手进行调查.首先了解到公司另一个部门有一套系统,能够实现Intranet ID登录.我就和那个系统的负责人联系,几封邮件往来之后,得知他们用的是一种叫到 LDAP 的技术.但他们是用的基于Notes平台的,而我们的系统是基于JSP + Tomcat的,他说他也帮不了太多忙.
        LDAP,一个我从来没有听说过的名词,只好从0开始学习.首先在百度百科里找到了关于它的一个比较详细的解释.通过那篇文章,我对LDAP是什么,能干什么有了比较清晰的了解.接下来就是上网找一些程序,首先找到的是一些如何操作LDAP的程序,但这需要一个管理员帐号和密码.这可把我给难住了,这么大一个公司,员工那么多,我不可能轻易拿到管理员级的帐号.
        我们部门还有另一个项目,他们在维护一个系统,这个系统也能实现Intranet ID 登录.不过他们的系统是用PHP写的,和我要找的东西还是没有太多直接联系.不过我从他们那里拿到了登录的源代码,通过研究源代码,我认识到不需要管理员级的帐号就可以实现用户Intranet ID登录.而且我还从源代码里找到了公司员工信息的LDAP server的URL 和根DN.
       但是当我用这些信息和自己的Intranet ID 和密码登录时,总是不成功,说是密码不对.但是,密码是没有问题的,因为我可以在别的系统里正常登录.我觉得问题还是出在用户名上.我就开始猜用户名到底是什么样的格式? 直接用 "yourname@myourdoain.com" 不行,用 "mail=yourname@myourdoain.com" 也不行.加上根DN, "mail=yourname@myourdoain.com,ou=catalogue,o=test.com", 还是不行. 后来经过不知多少次的尝试,终于发现每个员工都对应一个节点,这个节点有一个名字,你可以用下面的方法得到这个名字,用这个名字再加上根DN就可以了,
SearchResult si = (SearchResult) obj;
userDN = si.getName();
就像这样: "uid=123456,c=cn,ou=catalogue,o=test.com" .
        最后总结出的思路就是先匿名登录LDAP服务器,查询到用户的一些必要信息,组装成登录用的用户ID,然后再用组装好的ID和用户输入的密码重新连接LDAP服务器,成功则表示用户名和密码正确,否则表示用户信息输入错误.
  
    源代码如下,仅供参考:

package com.test.ldap;

import java.util.Hashtable;

import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
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;



public class UserAuthenticate {
    private String URL = "ldap://localhost:389/";
    private String BASEDN = "ou=catalogue,o=test.com";
    private String FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";
    private LdapContext ctx = null;
    private Hashtable env = null;
    private Control[] connCtls = null;
  
  
    private void LDAP_connect(){
        env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY,FACTORY);
        env.put(Context.PROVIDER_URL, URL+BASEDN);//LDAP server
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
//此处若不指定用户名和密码,则自动转换为匿名登录
      
        try{
            ctx = new InitialLdapContext(env,connCtls);
        }catch(javax.naming.AuthenticationException e){
            System.out.println("Authentication faild: "+e.toString());
        }catch(Exception e){
            System.out.println("Something wrong while authenticating: "+e.toString());
        }
    }
  
  
    private String getUserDN(String email){
        String userDN = "";
      
        LDAP_connect();
      
        try{
               SearchControls constraints = new SearchControls();
               constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
               NamingEnumeration en = ctx.search("", "mail="+email, constraints); //The UID you are going to query,* means all nodes
               if(en == null){
                System.out.println("Have no NamingEnumeration.");
               }
               if(!en.hasMoreElements()){
                System.out.println("Have no element.");
               }
               while (en != null && en.hasMoreElements()){//maybe more than one element
                   Object obj = en.nextElement();
                   if(obj instanceof SearchResult){
                       SearchResult si = (SearchResult) obj;
                       userDN += si.getName();
                       userDN += "," + BASEDN;
                   }
                   else{
                       System.out.println(obj);
                   }
                   System.out.println();
               }
              }catch(Exception e){
               System.out.println("Exception in search():"+e);
              }
      
        return userDN;
    }
  
  
    public boolean authenricate(String ID,String password){
        boolean valide = false;
        String userDN = getUserDN(ID);
      
        try {
            ctx.addToEnvironment(Context.SECURITY_PRINCIPAL,userDN);
            ctx.addToEnvironment(Context.SECURITY_CREDENTIALS,password);
            ctx.reconnect(connCtls);
            System.out.println(userDN + " is authenticated");
            valide = true;
        }catch (AuthenticationException e) {
            System.out.println(userDN + " is not authenticated");
            System.out.println(e.toString());
            valide = false;
        }catch (NamingException e) {
            System.out.println(userDN + " is not authenticated");
            valide = false;
        }
      
        return valide;
    }
}
分享到:
评论
1 楼 a49688448 2011-10-28  
LZ还在IBM工作么

相关推荐

    应用服务器中间件技术要求.doc

    应 " " "提供较大型系统集群应用案例。 " " "支持会话亲和。均衡负载策略支持简单轮转、加权轮转" " "、随机、备份等方式。 " " "必须支持异构Cluster。即当硬件平台或操作系统不是 " " "同一产品时,Web应用服务器...

    k8s集群部署Harbor镜像仓库

    本地镜像存储: Harbor提供了一个本地的、私有的镜像存储库,允许你在本地集群内管理...集成CI/CD可以帮助加速应用程序的开发和发布过程。 版本控制和回滚: Harbor支持版本控制,你可以追踪每个镜像的历史变更,这在

    JAVA上百实例源码以及开源项目源代码

     Java波浪文字,一个利用Java处理字符的实例,可以设置运动方向参数,显示文本的字符数组,高速文本颜色,显示字体的 FontMetrics对象,得到Graphics实例,得到Image实例,填充颜色数组数据,初始化颜色数组。...

    StrongKey CryptoEngine:FIDO强大的身份验证,加密,数字签名引擎-开源

    具有FIPS 140-2 HSM支持的数字签名文档,代码等的签名引擎-用于AD / LDAP集成以进行授权决策的LDAP引擎SKCE经过了实战测试并在其中在全球最大的电子商务公司之一进行生产,在业务流程中保护超过5000万个文档;...

    rstwiki:简单的reSTwiki系统

    依存关系猎豹> = 2.4 CherryPy> = 3.1.2 Docutils> = 0.5 Python> = 2.6 Pygments> = 1.4可选依赖项GitDB == 0.5.2(VCS集成所需) GitPython> = 0.3.1(VCS集成必需) python-ldap> = 2.4(LDAP认证必需) 狮身人面...

    php网络开发完全手册

    17.3 Session应用实例——登录验证 286 17.3.1 数据库设计 286 17.3.2 HTML表单的设计 287 17.3.3 验证页面的编写 287 17.3.4 欢迎页面的编写 288 17.3.5 注销页面的编写 288 17.3.6 代码的运行 289 17.3.7 代码的...

    JAVA上百实例源码以及开源项目

     Java波浪文字,一个利用Java处理字符的实例,可以设置运动方向参数,显示文本的字符数组,高速文本颜色,显示字体的 FontMetrics对象,得到Graphics实例,得到Image实例,填充颜色数组数据,初始化颜色数组。...

    MaxKey单点登录认证系统-其他

    3、提供标准的认证接口以便于其他应用集成SSO,安全的移动接入,安全的API、第三方认证和互联网认证的整合。 4、提供用户生命周期管理,支持SCIM 2协议,基于Apache Kafka代理,通过连接器(Connector)实现身份供给...

    网络安全设备技术要求.doc

    设备接口具备:" " "火墙 " "华为 " 4个千兆电口、2个千兆光口,1个RJ45串口,支持故障时BYPASS, " " " " " "多合一功能集成,需提供产品具备传统防火墙、流量管理、应用控制、僵尸网络检测、IPS入侵防 " " " " " ...

    网络安全设备技术要求(1).doc

    设备接口具备:" " "火墙 " "华为 " 4个千兆电口、2个千兆光口,1个RJ45串口,支持故障时BYPASS, " " " " " "多合一功能集成,需提供产品具备传统防火墙、流量管理、应用控制、僵尸网络检测、IPS入侵防 " " " " " ...

    asf-platform:ASF 平台 – CICD 基础设施的完整工作安装 – 工作且随时可用。 与示例“参考项目”源代码捆绑在一起,但也为其他类似项目做好准备

    敏捷软件工厂 入门 概述 敏捷软件工厂是高效、可扩展和可靠的开发和发布过程的基础。 通过在传送带或管道之后对流程进行建模,ASF 为您的软件开发流程...Docker VM - 用于部署 CI 应用程序以进行集成测试的实例 ASF

    从无到有搭建中小型互联网公司后台服务架构与运维架构

    课程将会通过实际案例讲解,并且会提供完整的视频案例源码供学员学习使用,同时有需要的企业或学员可以直接拿本套教学案例代码来使用或者二次开发。 本课程设计的技术及工具如下: 后台服务架构:dubbo、spring-...

    [完整][中文][WEB安全测试].(美)霍普.扫描版.pdf

    与即兴的安全评估不同的是,这些秘诀是可重复的、简洁的、系统的——可以完美地集成到你的常规测试套装中。  本书中的秘诀所覆盖的基础知识包括了从观察客户端和服务器之间的消息到使用脚本完成登录并执行Web应用...

    ASP3《高级编程》(第一部分)

    13.3.5 组件集成 423 13.3.6 建立组件 424 13.4 应用程序设计范例的研究 425 13.4.1 明确问题 425 13.4.2 应用程序的设计 426 13.4.3 设计权衡 430 13.4.4 设计小结 431 13.5 小结 432 第14章 COM、COM+和...

    ASP3《高级编程》(第二部分)

    13.3.5 组件集成 423 13.3.6 建立组件 424 13.4 应用程序设计范例的研究 425 13.4.1 明确问题 425 13.4.2 应用程序的设计 426 13.4.3 设计权衡 430 13.4.4 设计小结 431 13.5 小结 432 第14章 COM、COM+和...

    Java核心技术II(第8版)

    7.15 平台集成 7.15.1 闪屏 7.15.2 启动桌面应用程序 7.15.3 系统托盘 第八章 JavaBean构件 8.1 为何是Bean? 8.2 编写Bean的过程 8.3 使用Bean构造应用程序 8.3.1 将Bean打包成JAR文件 8.3.2 在开发环境中组合Bean...

    java开源包1

    LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持很多特性例如文件传输、...

    java开源包2

    LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持很多特性例如文件传输、...

    java开源包3

    LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持很多特性例如文件传输、...

Global site tag (gtag.js) - Google Analytics