栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何通过TLS上的LDAP对Active Directory进行身份验证?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何通过TLS上的LDAP对Active Directory进行身份验证?

好的,经过大约一天半的研究,我弄清楚了。

我最初的方法是扩展Spring的

ActiveDirectoryLdapAuthenticationProvider
类,并覆盖其
loadUserAuthorities()
方法,以便自定义身份验证用户权限的构建方式。由于不明显的原因,
ActiveDirectoryLdapAuthenticationProvider
该类被指定为
final
,因此我当然不能扩展它。

值得庆幸的是,开源提供了黑客手段(而该类的超类 不是

final
),因此我只是复制了它的全部内容,删除了
final
名称,并相应地调整了包和类的引用。我没有编辑此类中的任何代码,只是添加了一个高度可见的注释,该注释说不要对其进行编辑。然后
OverrideActiveDirectoryLdapAuthenticationProvider
,我在中扩展了该类,我也在
ldap.xml
文件中引用了该类,并在其中添加了重写方法
loadUserAuthorities
。通过在未加密会话上(在隔离的虚拟服务器上)的简单LDAP绑定,所有这些工作都很好。

实际的网络环境要求所有LDAP查询均以TLS握手开始,但是,要查询的服务器不是PDC,其名称为“ sub.domain.tld”,但已根据“
domain.tld”对用户进行了正确的身份验证。” 此外,用户名必须以“ NT_DOMAIN
”开头才能进行绑定。所有这些都需要自定义工作,但不幸的是,我在任何地方都没有或几乎没有帮助。

因此,这是荒谬的简单更改,所有这些更改都包含以下进一步的覆盖

OverrideActiveDirectoryLdapAuthenticationProvider

@Overrideprotected DirContext bindAsUser(String username, String password) {    final String bindUrl = url; //super reference    Hashtable<String,String> env = new Hashtable<String,String>();    env.put(Context.SECURITY_AUTHENTICATION, "simple");    //String bindPrincipal = createBindPrincipal(username);    String bindPrincipal = "NT_DOMAIN\" + username; //the bindPrincipal() method builds the principal name incorrectly    env.put(Context.SECURITY_PRINCIPAL, bindPrincipal);    env.put(Context.PROVIDER_URL, bindUrl);    env.put(Context.SECURITY_CREDENTIALS, password);    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxtFactory");    //and finally, this simple addition    env.put(Context.SECURITY_PROTOCOL, "tls");    //. . . try/catch portion left alone}

也就是说,我对该方法所做的全部工作就是更改了

bindPrincipal
字符串格式化的方式,并向哈希表添加了键/值。

我不必从

domain
传递给我的类的参数中删除子域,因为它是由
ldap.xml
; 传递的;我只是改变了参数 存在
<constructor-arg value="domain.tld"/>

然后我更改了

searchForUser()
方法
OverrideActiveDirectoryLdapAuthenticationProvider

@Overrideprotected DirContextOperations searchForUser(DirContext ctx, String username) throws NamingException {    SearchControls searchCtls = new SearchControls();    searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);    //this doesn't work, and I'm not sure exactly what the value of the parameter {0} is    //String searchFilter = "(&(objectClass=user)(userPrincipalName={0}))";    String searchFilter = "(&(objectClass=user)(userPrincipalName=" + username + "@domain.tld))";    final String bindPrincipal = createBindPrincipal(username);    String searchRoot = rootDn != null ? rootDn : searchRootFromPrincipal(bindPrincipal);    return SpringSecurityLdapTemplate.searchForSingleEntryInternal(ctx, searchCtls, searchRoot, searchFilter, new Object[]{bindPrincipal});

最后的更改是

createBindPrincipal()
方法,以正确构建String(出于我的目的):

@OverrideString createBindPrincipal(String username) {    if (domain == null || username.toLowerCase().endsWith(domain)) {        return username;    }    return "NT_DOMAIN\" + username;}

有了以上更改-我仍然需要从所有测试和总公司中清除这些更改-我得以针对自己在网络上的Active
Directory进行绑定和身份验证,捕获所需的任何用户对象字段,确定组成员身份等

哦,显然TLS不需要’ldaps://’,所以我

ldap.xml
只需使用
ldap://192.168.0.3:389


tl; dr

要启用TLS,请复制Spring的

ActiveDirectoryLdapAuthenticationProvider
类,删除该
final
名称,在自定义类中对其进行扩展,然后
bindAsUser()
通过添加
env.put(Context.SECURITY_PROTOCOL,"tls");
到环境哈希表进行覆盖。而已。

要更严格地控​​制绑定用户名,域和LDAP查询字符串,请适当地覆盖适用的方法。在我的情况下,我不能仅确定的值

{0}
是什么,因此我将其完全删除,
username
而是插入了传递的字符串。

希望有人能对您有所帮助。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/498407.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号