声明:

1、解决办法是从一个英文网站找到的,现在找不到了,不是我自己解决的

2、连接ldap的方法,也是从网上拷贝,因为方法是固定和通用的

3、欢迎拍砖和开骂,真的,但是至少骂完后告诉我哪里不对,教小弟几招


    前一阵子需要做一个从第三方ldap同步用户到本地系统的功能,本地后台服务是java写的,考虑到数据同步的一致性,使用ldap获取的数据中的的objectGUID作为两个系统的唯一标示


    但是问题来了,objectGUID这个东西貌似是octString类型的,本地服务获取时,居然出现了乱码。在网上找了好多方法,无外乎都是转换成String然后getBytes(),然后通过一系列的算法操作转换为16进制码等等。

    好吧,基本上,是这样的

......//连接ldap和查询代码省略

if("objectGUID".equals(Attr.getID())){  
    String st = getGUID(Attr.get().toString().getBytes()); //objectGUID
    
......//后续处理代码省略

}//方法结束

private static String getGUID(byte[] inArr) {  

    StringBuffer guid = new StringBuffer();  
    
        for (int i = 0; i < inArr.length; i++) {  
            StringBuffer dblByte = new StringBuffer(  
                    Integer.toHexString(inArr[i] & 0xff));  
            if (dblByte.length() == 1) {  
                guid.append("0");  
            }  
            guid.append(dblByte);  
        }  
        return guid.toString();  
    }


    不知道是我没有搞清楚原理还是什么原因,上面这种方法,因为先把取出来的值toString了一次,在不同的服务器(计算机)上,转换出来的十六进制码是不同的,具体原因待查。这样对将来的备份和数据迁移肯定是灾难!!!


    下面这种方法就好多了,而且还原了ldap服务器上的呈现形式,比如:

objectGUID:{751837D8-A40F-4F78-AE6C-29E2AD8D9921}


	public static void main(String[] args) {

		String adminName = "test@com.cn";			 // 账号
		String adminPassword = "123456"; 			 // 密码
		String ldapURL = "ldap://192.168.0.123:389"; // 地址

		Properties env = new Properties();

		env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
		env.put(Context.SECURITY_AUTHENTICATION, "simple");// "none","simple","strong"
		env.put(Context.SECURITY_PRINCIPAL, adminName);
		env.put(Context.SECURITY_CREDENTIALS, adminPassword);
		env.put(Context.PROVIDER_URL, ldapURL);
		
		//	**解决 乱码 的关键一句
		env.put("java.naming.ldap.attributes.binary","objectGUID");	

		try {
			
			//	建立连接
			LdapContext ctx = new InitialLdapContext(env, null);
			
			//	定义要取出的属性
			String returnedAtts[] = { 
					"cn", 
					"sn", 
					"givenname",
					"distinguishedName", 
					"displayname", 
					"objectCategory",
					"objectClass", 
					"objectGUID", 
					"objectSid",
					"userAccountControl", 
					"name", 
					"distinguishedName" 
			};
			SearchControls searchCtls = new SearchControls();
			searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
			searchCtls.setReturningAttributes(returnedAtts);

			//	定义条件
			String searchFilter = "(&(objectClass=person)(objectClass=organizationalPerson)(objectClass=user)(!(objectClass=computer)))";
			String searchBase = "DC=com,DC=cn";

			//	执行查询
			NamingEnumeration<SearchResult> answer = ctx.search(searchBase,searchFilter, searchCtls);
			while (answer.hasMoreElements()) {

				SearchResult sr = (SearchResult) answer.next();
//				System.out.println(sr.getAttributes().get("distinguishedName")
//						.toString()
//						+ " || "
//						+ sr.getAttributes().get("userAccountControl").toString()
//						+ " || "
//						+ sr.getAttributes().get("objectClass").toString()
//						+ " || "
//						+ sr.getAttributes().get("name").toString()
//						+ " || "
//						+ sr.getAttributes().get("objectGUID").toString());
				
				byte[] GUID = (byte[])sr.getAttributes().get("objectGUID").get();
                
				String strGUID = "";
                String byteGUID = "";
                
                
                //Convert the GUID into string using the byte format
                for (int c=0;c<GUID.length;c++) {
                     byteGUID = byteGUID + "\\" + AddLeadingZero((int)GUID[c] & 0xFF);
                }
                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);
                strGUID = strGUID + "}";
                System.out.println(sr.getAttributes().get("name"));
                System.out.println("GUID (String format): " + strGUID);
                //System.out.println("GUID (Byte format): " + byteGUID);

			}
			
			
			ctx.close();
		} catch (NamingException e) {
			e.printStackTrace();
			System.err.println("Problem searching directory: " + e);
		}
	}

	public static String AddLeadingZero(int k) {
		return (k <= 0xF) ? "0" + Integer.toHexString(k) : Integer
				.toHexString(k);
	}