Groovy查询AD时com.sun.jndi.ldap.LdapAttribute的objectGUID编码错误问题
解决方法
问题根因
Active Directory返回的objectGUID是16位二进制字节数组,并非普通字符串类型,你直接调用toString()会输出字节的内存乱码,无法得到可读格式。
修复步骤
- 不要对
objectGUID属性调用toString(),直接获取原始二进制值 - 编写字节序转换方法:AD存储的GUID采用混合字节序,前3段(4字节、2字节、2字节)为小端序,后2段(共8字节)为大端序,需要调整字节顺序后再转换为标准UUID格式
完整修改后代码
import javax.naming.directory.* import java.util.UUID // GUID转换工具方法 def convertAdGuidToString(byte[] guidBytes) { byte[] adjusted = new byte[16] // 调整前4字节顺序 adjusted[0] = guidBytes[3] adjusted[1] = guidBytes[2] adjusted[2] = guidBytes[1] adjusted[3] = guidBytes[0] // 调整第2组2字节顺序 adjusted[4] = guidBytes[5] adjusted[5] = guidBytes[4] // 调整第3组2字节顺序 adjusted[6] = guidBytes[7] adjusted[7] = guidBytes[6] // 后8字节直接复制 System.arraycopy(guidBytes, 8, adjusted, 8, 8) // 生成标准UUID字符串 long msb = new BigInteger(1, adjusted[0..7] as byte[]).longValue() long lsb = new BigInteger(1, adjusted[8..15] as byte[]).longValue() return new UUID(msb, lsb).toString() } // base OU for our search GRP_OU = 'OU=cust,DC=example,DC=com' mkCtx = {param = [:] -> new InitialDirContext( (Hashtable)param.collect { k, v -> [InitialDirContext[k], v.toString()] }.collectEntries() ) } mkCtx(PROVIDER_URL: "ldap://example.com:389", INITIAL_CONTEXT_FACTORY: 'com.sun.jndi.ldap.LdapCtxFactory', SECURITY_AUTHENTICATION: 'simple', SECURITY_PRINCIPAL: "CN=user,DC=example,DC=com", SECURITY_CREDENTIALS: 'password', ).search( GRP_OU, '(&(mail=ldaptest@example.de)(memberof=group,DC=example,DC=com))', new SearchControls([searchScope: SearchControls.SUBTREE_SCOPE]) ).each { entry -> def attributes = ['sn', 'givenName', 'sAMAccountName', 'memberOf', 'objectGUID'] def attrValues = attributes.collect { entry.attributes.get(it)?.get() } // 输出普通字符串属性 println(attrValues[0]) println(attrValues[1]) println(attrValues[2]) println(attrValues[3]) // 转换并输出可读GUID println(convertAdGuidToString(attrValues[4] as byte[])) }
效果说明
修改后输出的objectGUID会是标准的xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx格式的可读字符串,无需额外处理。
内容的提问来源于stack exchange,提问作者Bltzz
相关产品推荐
相关产品推荐

