zoukankan      html  css  js  c++  java
  • JAVA 通过LDAP获取AD域用户及组织信息

    因为工作需求近期做过一个从客户AD域获取数据实现单点登录的功能,在此整理分享。

    前提:用户可能有很多系统的情况下,为了方便账号的统一管理使用AD域验证登录,所以不需要我们的系统登录,就需要获取用户的AD域组织和用户信息,实现域认证和单点登录。

    LDAP: LDAP是轻量目录访问协议

    AD域:微软基于域模式的集中化管理

    1.常规的AD域登陆验证

    LdapContext dc = null;
                Hashtable<String, String> env = new Hashtable<String, String>();
                env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
                env.put(Context.PROVIDER_URL, "ldap://ld.123.com:389");//AD域路径和端口号
                env.put(Context.SECURITY_AUTHENTICATION, "simple");
                env.put(Context.SECURITY_PRINCIPAL, username);
                env.put(Context.SECURITY_CREDENTIALS, password);
                env.put(Context.REFERRAL, "throw");
                env.put("java.naming.ldap.attributes.binary", "objectGUID");// objectGUID也可以指定为其它属性
                
                try {
                    DirContext ctx = new InitialDirContext(env);
                    System.out.println("认证成功");
                    ctx.close();
                } catch (Exception e) {
                    System.out.println("认证失败");
                }

     

    2.获取AD域用户组织及属性信息

    获取AD域连接:

    private static void entryActiveDirectory() throws NamingException {

               LdapContext dc = null;

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

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

               env.put(Context.PROVIDER_URL, "ldap://ld.123.com:389");

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

               env.put(Context.SECURITY_PRINCIPAL, " ld\admin");

               env.put(Context.SECURITY_CREDENTIALS, passwprd);

               env.put(Context.REFERRAL, "throw");

               dc = new InitialLdapContext(env, null);

               String dn="OU=集团总部,OU=Greenland,DC=ld,DC=Greenland,DC=com";

               processOrganize(dc,dn);

           }

    数据处理

    //要获取的对象属性

    private static String[] attributeNames = { "memberOf", "name", "userPrincipalName", "objectClass", "objectGUID","sAMAccountName","description" };

    NamingEnumeration<?> contentsEnum = dc.list(dn);

    while (contentsEnum.hasMore()) {

    NameClassPair ncp = (NameClassPair) contentsEnum.next();

                   String ncpName = ncp.getName();

                   // 对特殊字符的DN跳过

    if ((ncpName + "," + dn).indexOf(""") != -1 || (ncpName + "," + dn).indexOf("/") != -1) {continue;}

    Attributes atts = dc.getAttributes(ncpName + "," + dn, attributeNames);

    //获取对象属性

    Attribute objectClassAuttribute = atts.get("objectClass");

                   if (objectClassAuttribute.toString().indexOf("user") != -1) {//获取用户是user,部门组织是organizationalUnit

                   System.out.println(atts+ncpName + "," + dn); }

               }

    3.GUID的处理方式

    objectguid是AD域组织和用户的唯一标识,当用户或组织修改名字后也不会发生变化,但是其他属性通过上面的方式都可以获取到正常值,包括中文。

    但是objectguid是个例外,正常情况下都会出现乱码,而且一般的转码方式都是无效的(本人已经尝试了许多种),通过网上多种方式搜寻的答案许多都不靠谱,

    最后在国外的一个论坛上找到了这个方法,首先声明下,这个方法获取的guid和AD域中看到的还是不一样的,但是,也是可以保证唯一性的,而且修改名字后,

    再次获取也不会发生变化,所以可用,以下的处理代码:

    Object oo= atts.get("objectguid").get();

                byte[] GUID = toByteArray(oo);

                     String strGUID = "";

                     strGUID = strGUID + AddLeadingZero((int)GUID[3] & 0xFF);

                     strGUID = strGUID + AddLeadingZero((int)GUID[2] & 0xFF);

                     strGUID = strGUID + AddLeadingZero((int)GUID[1] & 0xFF);

                     strGUID = strGUID + AddLeadingZero((int)GUID[0] & 0xFF);

                     strGUID = strGUID + "-";

                     strGUID = strGUID + AddLeadingZero((int)GUID[5] & 0xFF);

                     strGUID = strGUID + AddLeadingZero((int)GUID[4] & 0xFF);

                     strGUID = strGUID + "-";

                     strGUID = strGUID + AddLeadingZero((int)GUID[7] & 0xFF);

                     strGUID = strGUID + AddLeadingZero((int)GUID[6] & 0xFF);

                     strGUID = strGUID + "-";

                     strGUID = strGUID + AddLeadingZero((int)GUID[8] & 0xFF);

                     strGUID = strGUID + AddLeadingZero((int)GUID[9] & 0xFF);

                     strGUID = strGUID + "-";

                     strGUID = strGUID + AddLeadingZero((int)GUID[10] & 0xFF);

                     strGUID = strGUID + AddLeadingZero((int)GUID[11] & 0xFF);

                     strGUID = strGUID + AddLeadingZero((int)GUID[12] & 0xFF);

                     strGUID = strGUID + AddLeadingZero((int)GUID[13] & 0xFF);

                     strGUID = strGUID + AddLeadingZero((int)GUID[14] & 0xFF);

                     strGUID = strGUID + AddLeadingZero((int)GUID[15] & 0xFF);

                     System.out.println("GUID (String format): " + strGUID);

  • 相关阅读:
    Apache Kafka源码分析
    Apache Kafka源码分析
    Apache Kafka源码分析
    Apache Kafka源码分析
    如何保障流式处理的数据一致性
    Tuning Spark
    Java内存管理和垃圾回收
    Spark MLlib
    Win7系统与它的Virtualbox中安装的Ubuntu14.04共享信息的几种方法
    图片流量节省大杀器:基于CDN的sharpP自适应图片技术实践
  • 原文地址:https://www.cnblogs.com/taleche/p/5377511.html
Copyright © 2011-2022 走看看