Java验证LDAP用户,如何返回详细的错误信息

时间:2022-10-30 16:13:24
使用以下Java代码验证LDAP用户,如果验证失败抛出异常Exception in thread "main" javax.naming.AuthenticationException: [LDAP: error code 49 - Invalid Credentials],怎么样才能确定验证失败的详细信息(如是账号锁定或者是密码过期)?

String FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";
LdapContext ctx = null;
Hashtable<String, String> env = null;
Control[] connCtls = null;

env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, FACTORY);
env.put(Context.PROVIDER_URL, "ldap://fli.abc.com:389");

env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL,
"uid=user1,ou=people,cn=EnterpriseLdap,o=org");
env.put(Context.SECURITY_CREDENTIALS, "123");

try {
ctx = new InitialLdapContext(env, connCtls);
} catch (NamingException e) {
e.printStackTrace();
} finally {
if (ctx != null) {
try {
ctx.close();
} catch (NamingException e) {
e.printStackTrace();
}
}
}

14 个解决方案

#1


有这么智能吗?
验证失败具体原因,需要程序查询后给出.

论坛好久前有讨论帖,供参考
http://bbs.csdn.net/topics/240043926

#2


引用 1 楼 brightyq 的回复:
有这么智能吗?
验证失败具体原因,需要程序查询后给出.

论坛好久前有讨论帖,供参考 http://bbs.csdn.net/topics/240043926


如果使用Active Directory 作为LDAP服务器是可以实现的,Active Directory在用户验证失败时返回的准确的错误代码。

#3


原来是有的


LDAP_SUCCESS = 0 //成功 
LDAP_OPERATIONS_ERROR = 1 //操作错误 
LDAP_PROTOCOL_ERROR = 2 //协议错误 
LDAP_TIME_LIMIT_EXCEEDED = 3 //超过最大时间限制 
LDAP_SIZE_LIMIT_EXCEEDED = 4 //超过最大返回条目数 
LDAP_COMPARE_FALSE = 5 //比较不匹配 
LDAP_COMPARE_TRUE = 6 //比较匹配 
LDAP_AUTH_METHOD_NOT_SUPPORTED = 7 //认证方法未被支持 
LDAP_STRONG_AUTH_REQUIRED = 8 //需要强认证 
LDAP_PARTIAL_RESULTS = 9 //null 
LDAP_REFERRAL = 10 //Referral 
LDAP_ADMIN_LIMIT_EXCEEDED = 11 //超出管理员权限 
LDAP_UNAVAILABLE_CRITICAL_EXTENSION = 12 //Critical扩展无效 
LDAP_CONFIDENTIALITY_REQUIRED = 13 //需要Confidentiality 
LDAP_SASL_BIND_IN_PROGRESS = 14 //需要SASL绑定 
LDAP_NO_SUCH_ATTRIBUTE = 16 //未找到该属性 
LDAP_UNDEFINED_ATTRIBUTE_TYPE = 17 //未定义的属性类型 
LDAP_INAPPROPRIATE_MATCHING = 18 //不适当的匹配 
LDAP_CONSTRAINT_VIOLATION = 19 //约束冲突 
LDAP_ATTRIBUTE_OR_value_EXISTS = 20 //属性或值已存在 
LDAP_INVALID_ATTRIBUTE_SYNTAX = 21 //无效的属性语法 
LDAP_NO_SUCH_OBJECT = 32 //未找到该对象 
LDAP_ALIAS_PROBLEM = 33 //别名有问题 
LDAP_INVALID_DN_SYNTAX = 34 //无效的DN语法 
LDAP_IS_LEAF = 35 //null 
LDAP_ALIAS_DEREFERENCING_PROBLEM = 36 //Dereference别名有问题 
LDAP_INAPPROPRIATE_AUTHENTICATION = 48 //不适当的认证 
LDAP_INVALID_CREDENTIALS = 49 //无效的Credential 
LDAP_INSUFFICIENT_ACCESS_RIGHTS = 50 //访问权限不够 
LDAP_BUSY = 51 //遇忙 
LDAP_UNAVAILABLE = 52 //无效 
LDAP_UNWILLING_TO_PERform = 53 //意外问题 
LDAP_LOOP_DETECT = 54 //发现死循环 
LDAP_NAMING_VIOLATION = 64 //命名冲突 
LDAP_OBJECT_CLASS_VIOLATION = 65 //对象类冲突 
LDAP_NOT_ALLOWED_ON_NON_LEAF = 66 //不允许在非叶结点执行此操作 
LDAP_NOT_ALLOWED_ON_RDN = 67 //不允许对RDN执行此操作 
LDAP_ENTRY_ALREADY_EXISTS = 68 //Entry已存在 
LDAP_OBJECT_CLASS_MODS_PROHIBITED = 69 //禁止更改对象类 
LDAP_AFFECTS_MULTIPLE_DSAS = 71 //null 
LDAP_OTHER = 80 //其它 

#4


返回错误信息的意义也可以参考这个

http://support.microsoft.com/kb/218185/zh-cn

#5


LDAP: error code 49 - Invalid Credentials

这个不是已经对应了具体的错误信息了吗?


LDAP_INVALID_CREDENTIALS          0x31   提供的凭据无效。

#6


引用 5 楼 dracularking 的回复:
LDAP: error code 49 - Invalid Credentials

这个不是已经对应了具体的错误信息了吗?


LDAP_INVALID_CREDENTIALS          0x31   提供的凭据无效。


LDAP: error code 49 - Invalid Credentials只是说明了凭据无效,无法确认到底是因为密码过期还是密码错误。在返回的错误信息中也没有0x31的标识。

#7


引用 3 楼 brightyq 的回复:
原来是有的


LDAP_SUCCESS = 0 //成功 
LDAP_OPERATIONS_ERROR = 1 //操作错误 
LDAP_PROTOCOL_ERROR = 2 //协议错误 
LDAP_TIME_LIMIT_EXCEEDED = 3 //超过最大时间限制 
LDAP_SIZE_LIMIT_EXCEEDED = 4 //超过最大返回条目数 
……


这些错误代码也没有细化到验证失败是因为账号锁定还是密码过期。

#8


我需要的是OpenDS实现像Active Directory的功能,对于验证失败,能够细分失败类型。

可参见下面链接,谢谢。
http://ldapwiki.willeke.com/wiki/Common%20Active%20Directory%20Bind%20Errors

#9


引用 6 楼 felixli_cn 的回复:
LDAP: error code 49 - Invalid Credentials只是说明了凭据无效,无法确认到底是因为密码过期还是密码错误。在返回的错误信息中也没有0x31的标识。 


0x31是在4楼的连接中对应查到的,貌似0x31本身也没有提供额外的信息

不过Invalid Credentials不就是密码无效吗? 密码过期归根结底也是密码无效,密码无效就要寻找有效的密码(包括激活)

楼主需要更详细的报错提示,已经解决这个问题了?

#10


引用 9 楼 dracularking 的回复:
引用 6 楼 felixli_cn 的回复:LDAP: error code 49 - Invalid Credentials只是说明了凭据无效,无法确认到底是因为密码过期还是密码错误。在返回的错误信息中也没有0x31的标识。 

0x31是在4楼的连接中对应查到的,貌似0x31本身也没有提供额外的信息

不过Invalid Credentials不就是密码无效吗……


dracularking这个问题已经找到解决办法了,OpenDS基于安全考虑,默认是关闭验证失败时输出详细错误信息功能的,需要修改配置打开。
参考链接:http://blogs.nologin.es/rickyepoderi/index.php?/archives/57-LDAP-password-policies-and-JavaEE.html

#11



设置OpenDS的return-bind-error-messages参数为true后,如果验证失败会抛出类似下面的错误。
密码错误信息:javax.naming.AuthenticationException: [LDAP: error code 49 - The password provided by the user did not match any password(s) stored in the user's entry]

账号锁定信息:javax.naming.AuthenticationException: [LDAP: error code 49 - Rejecting a bind request for user uid=user1,ou=people,cn=EnterpriseLdap,o=org because the account has been locked due to too many failed authentication attempts]

#12


引用 10 楼 felixli_cn 的回复:
dracularking这个问题已经找到解决办法了,OpenDS基于安全考虑,默认是关闭验证失败时输出详细错误信息功能的,需要修改配置打开。
参考链接:http://blogs.nologin.es/rickyepoderi/index.php?/archives/57-LDAP-password-policies-and-JavaEE.html


谢谢非常详细告知,楼主本来就用的OpenDS吗? 

#13


引用 11 楼 felixli_cn 的回复:
设置OpenDS的return-bind-error-messages参数为true后,如果验证失败会抛出类似下面的错误。
密码错误信息:javax.naming.AuthenticationException: [LDAP: error code 49 - The password provided by the user did not match any password(s) stored in the user's entry]


确实在最后有提到:
[1] By default OpenDS does not give a detailed error response (security reasons). It should be configured like this:

$ ./dsconfig set-global-configuration-prop -h localhost -p 4444 --trustAll \
  -D "cn=Directory Manager" -w **** -n --set return-bind-error-messages:true

#14


我用的就是OpenDS

#1


有这么智能吗?
验证失败具体原因,需要程序查询后给出.

论坛好久前有讨论帖,供参考
http://bbs.csdn.net/topics/240043926

#2


引用 1 楼 brightyq 的回复:
有这么智能吗?
验证失败具体原因,需要程序查询后给出.

论坛好久前有讨论帖,供参考 http://bbs.csdn.net/topics/240043926


如果使用Active Directory 作为LDAP服务器是可以实现的,Active Directory在用户验证失败时返回的准确的错误代码。

#3


原来是有的


LDAP_SUCCESS = 0 //成功 
LDAP_OPERATIONS_ERROR = 1 //操作错误 
LDAP_PROTOCOL_ERROR = 2 //协议错误 
LDAP_TIME_LIMIT_EXCEEDED = 3 //超过最大时间限制 
LDAP_SIZE_LIMIT_EXCEEDED = 4 //超过最大返回条目数 
LDAP_COMPARE_FALSE = 5 //比较不匹配 
LDAP_COMPARE_TRUE = 6 //比较匹配 
LDAP_AUTH_METHOD_NOT_SUPPORTED = 7 //认证方法未被支持 
LDAP_STRONG_AUTH_REQUIRED = 8 //需要强认证 
LDAP_PARTIAL_RESULTS = 9 //null 
LDAP_REFERRAL = 10 //Referral 
LDAP_ADMIN_LIMIT_EXCEEDED = 11 //超出管理员权限 
LDAP_UNAVAILABLE_CRITICAL_EXTENSION = 12 //Critical扩展无效 
LDAP_CONFIDENTIALITY_REQUIRED = 13 //需要Confidentiality 
LDAP_SASL_BIND_IN_PROGRESS = 14 //需要SASL绑定 
LDAP_NO_SUCH_ATTRIBUTE = 16 //未找到该属性 
LDAP_UNDEFINED_ATTRIBUTE_TYPE = 17 //未定义的属性类型 
LDAP_INAPPROPRIATE_MATCHING = 18 //不适当的匹配 
LDAP_CONSTRAINT_VIOLATION = 19 //约束冲突 
LDAP_ATTRIBUTE_OR_value_EXISTS = 20 //属性或值已存在 
LDAP_INVALID_ATTRIBUTE_SYNTAX = 21 //无效的属性语法 
LDAP_NO_SUCH_OBJECT = 32 //未找到该对象 
LDAP_ALIAS_PROBLEM = 33 //别名有问题 
LDAP_INVALID_DN_SYNTAX = 34 //无效的DN语法 
LDAP_IS_LEAF = 35 //null 
LDAP_ALIAS_DEREFERENCING_PROBLEM = 36 //Dereference别名有问题 
LDAP_INAPPROPRIATE_AUTHENTICATION = 48 //不适当的认证 
LDAP_INVALID_CREDENTIALS = 49 //无效的Credential 
LDAP_INSUFFICIENT_ACCESS_RIGHTS = 50 //访问权限不够 
LDAP_BUSY = 51 //遇忙 
LDAP_UNAVAILABLE = 52 //无效 
LDAP_UNWILLING_TO_PERform = 53 //意外问题 
LDAP_LOOP_DETECT = 54 //发现死循环 
LDAP_NAMING_VIOLATION = 64 //命名冲突 
LDAP_OBJECT_CLASS_VIOLATION = 65 //对象类冲突 
LDAP_NOT_ALLOWED_ON_NON_LEAF = 66 //不允许在非叶结点执行此操作 
LDAP_NOT_ALLOWED_ON_RDN = 67 //不允许对RDN执行此操作 
LDAP_ENTRY_ALREADY_EXISTS = 68 //Entry已存在 
LDAP_OBJECT_CLASS_MODS_PROHIBITED = 69 //禁止更改对象类 
LDAP_AFFECTS_MULTIPLE_DSAS = 71 //null 
LDAP_OTHER = 80 //其它 

#4


返回错误信息的意义也可以参考这个

http://support.microsoft.com/kb/218185/zh-cn

#5


LDAP: error code 49 - Invalid Credentials

这个不是已经对应了具体的错误信息了吗?


LDAP_INVALID_CREDENTIALS          0x31   提供的凭据无效。

#6


引用 5 楼 dracularking 的回复:
LDAP: error code 49 - Invalid Credentials

这个不是已经对应了具体的错误信息了吗?


LDAP_INVALID_CREDENTIALS          0x31   提供的凭据无效。


LDAP: error code 49 - Invalid Credentials只是说明了凭据无效,无法确认到底是因为密码过期还是密码错误。在返回的错误信息中也没有0x31的标识。

#7


引用 3 楼 brightyq 的回复:
原来是有的


LDAP_SUCCESS = 0 //成功 
LDAP_OPERATIONS_ERROR = 1 //操作错误 
LDAP_PROTOCOL_ERROR = 2 //协议错误 
LDAP_TIME_LIMIT_EXCEEDED = 3 //超过最大时间限制 
LDAP_SIZE_LIMIT_EXCEEDED = 4 //超过最大返回条目数 
……


这些错误代码也没有细化到验证失败是因为账号锁定还是密码过期。

#8


我需要的是OpenDS实现像Active Directory的功能,对于验证失败,能够细分失败类型。

可参见下面链接,谢谢。
http://ldapwiki.willeke.com/wiki/Common%20Active%20Directory%20Bind%20Errors

#9


引用 6 楼 felixli_cn 的回复:
LDAP: error code 49 - Invalid Credentials只是说明了凭据无效,无法确认到底是因为密码过期还是密码错误。在返回的错误信息中也没有0x31的标识。 


0x31是在4楼的连接中对应查到的,貌似0x31本身也没有提供额外的信息

不过Invalid Credentials不就是密码无效吗? 密码过期归根结底也是密码无效,密码无效就要寻找有效的密码(包括激活)

楼主需要更详细的报错提示,已经解决这个问题了?

#10


引用 9 楼 dracularking 的回复:
引用 6 楼 felixli_cn 的回复:LDAP: error code 49 - Invalid Credentials只是说明了凭据无效,无法确认到底是因为密码过期还是密码错误。在返回的错误信息中也没有0x31的标识。 

0x31是在4楼的连接中对应查到的,貌似0x31本身也没有提供额外的信息

不过Invalid Credentials不就是密码无效吗……


dracularking这个问题已经找到解决办法了,OpenDS基于安全考虑,默认是关闭验证失败时输出详细错误信息功能的,需要修改配置打开。
参考链接:http://blogs.nologin.es/rickyepoderi/index.php?/archives/57-LDAP-password-policies-and-JavaEE.html

#11



设置OpenDS的return-bind-error-messages参数为true后,如果验证失败会抛出类似下面的错误。
密码错误信息:javax.naming.AuthenticationException: [LDAP: error code 49 - The password provided by the user did not match any password(s) stored in the user's entry]

账号锁定信息:javax.naming.AuthenticationException: [LDAP: error code 49 - Rejecting a bind request for user uid=user1,ou=people,cn=EnterpriseLdap,o=org because the account has been locked due to too many failed authentication attempts]

#12


引用 10 楼 felixli_cn 的回复:
dracularking这个问题已经找到解决办法了,OpenDS基于安全考虑,默认是关闭验证失败时输出详细错误信息功能的,需要修改配置打开。
参考链接:http://blogs.nologin.es/rickyepoderi/index.php?/archives/57-LDAP-password-policies-and-JavaEE.html


谢谢非常详细告知,楼主本来就用的OpenDS吗? 

#13


引用 11 楼 felixli_cn 的回复:
设置OpenDS的return-bind-error-messages参数为true后,如果验证失败会抛出类似下面的错误。
密码错误信息:javax.naming.AuthenticationException: [LDAP: error code 49 - The password provided by the user did not match any password(s) stored in the user's entry]


确实在最后有提到:
[1] By default OpenDS does not give a detailed error response (security reasons). It should be configured like this:

$ ./dsconfig set-global-configuration-prop -h localhost -p 4444 --trustAll \
  -D "cn=Directory Manager" -w **** -n --set return-bind-error-messages:true

#14


我用的就是OpenDS