Spring LDAP获取AD用户正确objectSid异常问题求助
解决Spring LDAP中无法获取正确Active Directory objectSid的问题
你的问题根源在于错误地将二进制类型的objectSid属性当作字符串处理了,这导致你拿到的不是原始的SID二进制数据,自然转换不出正确的SID字符串。
问题分析
在Active Directory中,objectSid是一个二进制属性,而非字符串类型。你当前代码里用ctx.getStringAttribute("objectSid")获取它时,LDAP客户端会尝试把二进制数据转成字符串(通常用默认编码),这个过程直接破坏了原始二进制结构,后续调用.getBytes()得到的字节数组根本不是AD存储的真实SID数据,所以每次转换出来都是同一个错误的固定值。
解决方案
改用DirContextOperations提供的二进制属性专属获取方法拿到原始SID字节数组,有两种可行方式:
- 使用
getBinaryAttribute()方法(Spring专为二进制属性设计的便捷方法) - 使用
getObjectAttribute()方法后强制转换为byte[]
修改你的LdapUserDetailsContextMapper对应代码即可:
@Slf4j public class LdapUserDetailsContextMapper implements UserDetailsContextMapper { @Override public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> collection) { log.info("username: " + username); log.info("DN from ctx: " + ctx.getDn()); // 方式1:用getBinaryAttribute直接获取二进制属性 byte[] byteSid = ctx.getBinaryAttribute("objectSid"); // 方式2:或用getObjectAttribute后强转(和方式1效果一致) // byte[] byteSid = (byte[]) ctx.getObjectAttribute("objectSid"); String sid = LdapUtils.convertBinarySidToString(byteSid); log.info("SID: " + sid); // 现在应该能拿到正确的SID了 return new User(username, "notUsed", true, true, true, true, AuthorityUtils.createAuthorityList("ROLE_USER")); } @Override public void mapUserToContext(UserDetails userDetails, DirContextAdapter dirContextAdapter) { } }
额外验证步骤
为确保结果正确,你可以用LDAP浏览器工具(比如Apache Directory Studio)连接AD服务器,找到目标用户:
- 确认
objectSid属性类型为Binary - 查看工具中转译后的SID字符串,和代码输出结果对比验证
内容的提问来源于stack exchange,提问作者kojot
相关产品推荐
相关产品推荐

