1、[LDAP: error code 34 - 00000057: LdapErr: DSID-0C090B60, comment: Error processing name, data 0, v1db1
在编辑AD域控帐号属性或密码的时候,经常会遇到这个错误;
为什么会产生这个错误?
我经过验证列举了几个错误的例子:
ldapContext.modifyAttributes(userDN, mods);//这是修改AD帐号密码的方法;
1)参数userDN如果不是这种格式(CN=张三,OU=测试,OU=**公司,DC=test,DC=com)就会报上面的错误;
2)参数userDN如果包含一些特殊符号,就会报上面的错误;
比如:userDN = CN=张三,OU=测试+研发,OU=**公司,DC=test,DC=com
userDN = CN=张三,OU=测试,研发,OU=**公司,DC=test,DC=com
userDN = CN=张三,OU=测试=研发,OU=**公司,DC=test,DC=com
上面的格式都会造成上面的错误,一定要把值进行转义才可以成功:
userDN = CN=张三,OU=测试\+研发,OU=**公司,DC=test,DC=com
userDN = CN=张三,OU=测试\,研发,OU=**公司,DC=test,DC=com
userDN = CN=张三,OU=测试\=研发,OU=**公司,DC=test,DC=com
体现代码就是:
userDN = userDN.replaceAll("\\+", "\\\\+");
userDN = userDN.replace("测试,研发", "测试\\,研发");
userDN = userDN.replace("测试,研发", "测试\\=研发");
2、[LDAP: error code 49 - 80090308: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 52e, v1db1
这个错误很常见,如果你在开发过程中遇到这个错误,说明:AD认证的帐号或密码不正确;
顺便多说一些使用场景:
AD认证,帐号的格式有很多种:
如果帐号属性:
sAMAccountName = zhangsan
distinguishedName = CN=张三,OU=测试\+研发,OU=**公司,DC=test,DC=com
那么帐号认证的方式可以是:
adminUID的形式会有三种,这三种可能跟AD域控的系统版本有关系,windows2008这三种方式都是兼容的,其他的未经过测试,需要验证;
property.put(DirContext.INITIAL_CONTEXT_FACTORY, LDAPEnv_Factory);
// 拥有Domain Admins角色的用户,域管理员
// adminUID的值可以为:adminUID = CN=张三,OU=测试\+研发,OU=**公司,DC=test,DC=com
// adminUID的值可以为:adminUID = zhangsan@test.com
// adminUID的值可以为:adminUID = test\zhangsan
property.put(Context.SECURITY_PRINCIPAL, adminUID);
property.put(Context.SECURITY_CREDENTIALS, adminPass);
property.put(Context.SECURITY_AUTHENTICATION, "simple");
【注意】如果AD帐号勾选了“用户下次登录时须更改密码”,也会报错。
3、[LDAP: error code 53 - 0000001F: SvcErr: DSID-031A120C, problem 5003 (WILL_NOT_PERFORM), data 0
这个错误也很常见,出现这个错误,一般情况是编辑AD域控的帐号属性或密码失败了。
而失败的原因有以下可能:
1)通过ldapContext.modifyAttributes(userDN, mods);修改帐号密码,需要AD开通SSL协议才行(即:通过636端口进行执行),报上面的错误,是因为使用的389端口进行执行的;
体现到代码:
property.put("java.naming.authoritative", "true");
property.put("java.naming.security.protocol", "ssl");
// 如果大家需要SkipSSLSocketFactory.java,可以联系Q Q:2753538510
property.put("java.naming.ldap.factory.socket","com.***.jndi.directory.SkipSSLSocketFactory");
property.put("java.naming.provider.url", "ldaps://x.x.x.x:636");
property.setProperty("java.naming.referral", "ignore");
作为研发人员,在建立socket连接或http/https连接的时候,习惯性增加超时时间,而AD/LDAP的连接也会习惯性增加这段:
property.put("com.sun.jndi.ldap.connect.timeout", "5000");
那么增加这一行代码, 就会造成AD的SSL连接错误:
javax.naming.CommunicationException: x.x.x.x:636 [Root exception is java.net.SocketException: Unconnected sockets not implemented]
去掉上面一行,就可以了。
2)说一下如何开通AD侧的SSL协议:
windows2012 参考该链接:教程活动目录 - 通过 SSL 启用 LDAP [ 一步一步] (techexpert.tips)
windows2008的步骤如下:
1、打开:管理工具》服务器管理器
2、添加角色,勾选Active Directory 证书服务
图中我已经安装过了,因此会看到是灰色的; 注意:安装步骤跟windows 2012的稍微有一点差别;
3、安装完SSL,需要重启计算机,重启后,再次打开:管理工具》服务器管理器
可以看到目录里已经有证书服务了:
使用内置程序测试验证636端口是否正常: