使用 Apache LDAP API 在下次登录 Active Directory 时强制更改密码
Force password change on next login with Active Directory using Apache LDAP API
我们使用 Active Directory (AD),当添加用户时,他们会设置密码和强制执行“用户必须在下次登录时更改密码”的标志,这会导致 AD 属性 pwdLastSet=0
我有一个 Java 应用程序使用 Apache LDAP API 进行身份验证,但是当我这样做时,我收到错误代码 49 INVALID_CREDENTIALS
并且没有更改密码的指示。
我如何使用 Apache LDAP API 检测到用户必须先更改密码?
我的简单验证器:
public void authenticate(String uid, String password) {
String status = "";
try {
LdapConnectionConfig config = new LdapConnectionConfig();
config.setUseSsl(true);
config.setLdapHost("activedirectory.domain.net");
config.setLdapPort(636);
config.setTrustManagers(new NoVerificationTrustManager());
config.setName(_ldapMgmtUser);
config.setCredentials(_ldapMgmtPassword);
final DefaultPoolableLdapConnectionFactory factory = new DefaultPoolableLdapConnectionFactory(config);
final LdapConnectionPool pool = new LdapConnectionPool(factory);
pool.setTestOnBorrow(true);
final LdapConnectionTemplate ldapConnectionTemplate = new LdapConnectionTemplate(pool);
final PasswordWarning warning = ldapConnectionTemplate.authenticate(_rootDn, "(sAMAccountName=" + uid + ")",
SearchScope.SUBTREE, password.toCharArray());
status = "User credentials authenticated";
if (warning != null) {
status = status + " \n Warning!!" + warning.toString();
}
System.out.println(status);
} catch (final PasswordException e) {
System.err.println("############# PasswordException #############");
status = e.toString();
e.printStackTrace();
} catch (Exception e) {
System.err.println("############# Exception #############");
e.printStackTrace();
} finally {
}
return;
}
我注意到当使用 LdapConnectionTemplate
和 authenticate(...)
(如上)时,它不会 return 异常中的任何有用的错误代码并且没有 PasswordWarning
。
这种情况 return 不应该是 PasswordWarning
吗?
https://nightlies.apache.org/directory/api/2.0.1/apidocs/org/apache/directory/ldap/client/template/PasswordWarning.html
如果我使用:
LdapNetworkConnection
和 connection.bind(...)
它 return 是一个 LdapException
和消息
80090308: LdapErr: DSID-0C090453, comment: AcceptSecurityContext error, data 773, v3839
其中 773 是预期的。
感觉LdapConnectionTemplate有(几个)bug
完整代码:
public void authenticateWithBind(String uid, String password) {
String status = "";
LdapConnection connection = null;
try {
LdapConnectionConfig config = new LdapConnectionConfig();
config.setUseSsl(true);
config.setLdapHost("activedirectory.domain.net");
config.setLdapPort(636);
config.setTrustManagers(new NoVerificationTrustManager());
config.setName(_ldapMgmtUser);
config.setCredentials(_ldapMgmtPassword);
connection = new LdapNetworkConnection(config);
connection.bind(_ldapMgmtUser, _ldapMgmtPassword);
EntryCursor cursor = connection.search(_rootDn, "(sAMAccountName=" + uid + ")", SearchScope.SUBTREE, "*");
while (cursor.next()) {
Entry entry = cursor.get();
System.out.println("DN: " + entry.getDn());
System.out.println("Attribute: " + entry.get("pwdLastSet"));
connection.bind(entry.getDn(), password);
status = "User credentials authenticated";
System.out.println(status);
}
} catch (LdapException e) {
System.err.println("############# LdapException #############");
e.printStackTrace();
System.err.println("Error message: " + e.getMessage());
} catch (Exception e) {
System.err.println("############# Exception #############");
e.printStackTrace();
System.err.println("Error message: " + e.getMessage());
} finally {
closeConnection(connection);
}
return;
}
我们使用 Active Directory (AD),当添加用户时,他们会设置密码和强制执行“用户必须在下次登录时更改密码”的标志,这会导致 AD 属性 pwdLastSet=0
我有一个 Java 应用程序使用 Apache LDAP API 进行身份验证,但是当我这样做时,我收到错误代码 49 INVALID_CREDENTIALS
并且没有更改密码的指示。
我如何使用 Apache LDAP API 检测到用户必须先更改密码?
我的简单验证器:
public void authenticate(String uid, String password) {
String status = "";
try {
LdapConnectionConfig config = new LdapConnectionConfig();
config.setUseSsl(true);
config.setLdapHost("activedirectory.domain.net");
config.setLdapPort(636);
config.setTrustManagers(new NoVerificationTrustManager());
config.setName(_ldapMgmtUser);
config.setCredentials(_ldapMgmtPassword);
final DefaultPoolableLdapConnectionFactory factory = new DefaultPoolableLdapConnectionFactory(config);
final LdapConnectionPool pool = new LdapConnectionPool(factory);
pool.setTestOnBorrow(true);
final LdapConnectionTemplate ldapConnectionTemplate = new LdapConnectionTemplate(pool);
final PasswordWarning warning = ldapConnectionTemplate.authenticate(_rootDn, "(sAMAccountName=" + uid + ")",
SearchScope.SUBTREE, password.toCharArray());
status = "User credentials authenticated";
if (warning != null) {
status = status + " \n Warning!!" + warning.toString();
}
System.out.println(status);
} catch (final PasswordException e) {
System.err.println("############# PasswordException #############");
status = e.toString();
e.printStackTrace();
} catch (Exception e) {
System.err.println("############# Exception #############");
e.printStackTrace();
} finally {
}
return;
}
我注意到当使用 LdapConnectionTemplate
和 authenticate(...)
(如上)时,它不会 return 异常中的任何有用的错误代码并且没有 PasswordWarning
。
这种情况 return 不应该是 PasswordWarning
吗?
https://nightlies.apache.org/directory/api/2.0.1/apidocs/org/apache/directory/ldap/client/template/PasswordWarning.html
如果我使用:
LdapNetworkConnection
和 connection.bind(...)
它 return 是一个 LdapException
和消息
80090308: LdapErr: DSID-0C090453, comment: AcceptSecurityContext error, data 773, v3839
其中 773 是预期的。
感觉LdapConnectionTemplate有(几个)bug
完整代码:
public void authenticateWithBind(String uid, String password) {
String status = "";
LdapConnection connection = null;
try {
LdapConnectionConfig config = new LdapConnectionConfig();
config.setUseSsl(true);
config.setLdapHost("activedirectory.domain.net");
config.setLdapPort(636);
config.setTrustManagers(new NoVerificationTrustManager());
config.setName(_ldapMgmtUser);
config.setCredentials(_ldapMgmtPassword);
connection = new LdapNetworkConnection(config);
connection.bind(_ldapMgmtUser, _ldapMgmtPassword);
EntryCursor cursor = connection.search(_rootDn, "(sAMAccountName=" + uid + ")", SearchScope.SUBTREE, "*");
while (cursor.next()) {
Entry entry = cursor.get();
System.out.println("DN: " + entry.getDn());
System.out.println("Attribute: " + entry.get("pwdLastSet"));
connection.bind(entry.getDn(), password);
status = "User credentials authenticated";
System.out.println(status);
}
} catch (LdapException e) {
System.err.println("############# LdapException #############");
e.printStackTrace();
System.err.println("Error message: " + e.getMessage());
} catch (Exception e) {
System.err.println("############# Exception #############");
e.printStackTrace();
System.err.println("Error message: " + e.getMessage());
} finally {
closeConnection(connection);
}
return;
}