/* See LICENSE for licensing and NOTICE for copyright. */
package org.ldaptive.auth;
import java.util.HashMap;
import java.util.Map;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.ldaptive.AbstractTest;
import org.ldaptive.AttributeModification;
import org.ldaptive.AttributeModificationType;
import org.ldaptive.Connection;
import org.ldaptive.ConnectionFactoryManager;
import org.ldaptive.Credential;
import org.ldaptive.DefaultConnectionFactory;
import org.ldaptive.LdapAttribute;
import org.ldaptive.LdapEntry;
import org.ldaptive.LdapException;
import org.ldaptive.ModifyOperation;
import org.ldaptive.ModifyRequest;
import org.ldaptive.ResultCode;
import org.ldaptive.ReturnAttributes;
import org.ldaptive.SearchResult;
import org.ldaptive.TestControl;
import org.ldaptive.TestUtils;
import org.ldaptive.auth.ext.ActiveDirectoryAccountState;
import org.ldaptive.auth.ext.ActiveDirectoryAuthenticationResponseHandler;
import org.ldaptive.auth.ext.PasswordPolicyAuthenticationResponseHandler;
import org.ldaptive.control.AuthorizationIdentityRequestControl;
import org.ldaptive.control.PasswordPolicyControl;
import org.ldaptive.pool.BlockingConnectionPool;
import org.ldaptive.pool.PooledConnectionFactory;
import org.ldaptive.pool.PooledConnectionFactoryManager;
import org.ldaptive.velocity.TemplateSearchDnResolver;
import org.ldaptive.velocity.UserContext;
import org.testng.AssertJUnit;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
/**
* Unit test for {@link Authenticator}.
*
* @author Middleware Services
*/
public class AuthenticatorTest extends AbstractTest
{
/** Invalid password test data. */
public static final String INVALID_PASSWD = "not-a-password";
/** Invalid filter test data. */
public static final String INVALID_FILTER = "(departmentNumber=1111)";
/** Entry created for auth tests. */
private static LdapEntry testLdapEntry;
/** Entry created for auth tests. */
private static LdapEntry specialCharsLdapEntry2;
/** Entry created for auth tests. */
private static LdapEntry specialCharsLdapEntry3;
/** Authenticator instance for concurrency testing. */
private Authenticator singleTLSAuth;
/** Authenticator instance for concurrency testing. */
private Authenticator singleSSLAuth;
/** Authenticator instance for concurrency testing. */
private Authenticator singleTLSDnAuth;
/** Authenticator instance for concurrency testing. */
private Authenticator singleSSLDnAuth;
/** Authenticator instance for concurrency testing. */
private Authenticator pooledTLSAuth;
/**
* Default constructor.
*
* @throws Exception if ldap cannot be constructed
*/
public AuthenticatorTest()
throws Exception
{
singleTLSAuth = TestUtils.createTLSAuthenticator();
singleSSLAuth = TestUtils.createSSLAuthenticator();
singleTLSDnAuth = TestUtils.createTLSDnAuthenticator();
singleSSLDnAuth = TestUtils.createSSLDnAuthenticator();
pooledTLSAuth = TestUtils.createTLSAuthenticator();
}
/**
* @param ldifFile to create.
*
* @throws Exception On test failure.
*/
@Parameters("createEntry6")
@BeforeClass(groups = {"auth"})
public void createAuthEntry(final String ldifFile)
throws Exception
{
final String ldif = TestUtils.readFileIntoString(ldifFile);
testLdapEntry = TestUtils.convertLdifToResult(ldif).getEntry();
super.createLdapEntry(testLdapEntry);
final AuthenticationHandler ah = pooledTLSAuth.getAuthenticationHandler();
final DefaultConnectionFactory cf =
(DefaultConnectionFactory) ((ConnectionFactoryManager) ah).getConnectionFactory();
final BlockingConnectionPool cp = new BlockingConnectionPool(cf);
final PooledConnectionFactory pcf = new PooledConnectionFactory(cp);
pooledTLSAuth.setAuthenticationHandler(new PooledBindAuthenticationHandler(pcf));
try {
cp.initialize();
} catch (UnsupportedOperationException e) {
// ignore if not supported
AssertJUnit.assertNotNull(e);
}
}
/**
* @param ldifFile to create.
*
* @throws Exception On test failure.
*/
@Parameters("createSpecialCharsEntry2")
@BeforeClass(groups = {"auth"})
public void createSpecialCharsEntry2(final String ldifFile)
throws Exception
{
final String ldif = TestUtils.readFileIntoString(ldifFile);
specialCharsLdapEntry2 = TestUtils.convertLdifToResult(ldif).getEntry();
super.createLdapEntry(specialCharsLdapEntry2);
}
/**
* @param ldifFile to create.
*
* @throws Exception On test failure.
*/
@Parameters("createSpecialCharsEntry3")
@BeforeClass(groups = {"auth"})
public void createSpecialCharsEntry3(final String ldifFile)
throws Exception
{
final String ldif = TestUtils.readFileIntoString(ldifFile);
specialCharsLdapEntry3 = TestUtils.convertLdifToResult(ldif).getEntry();
super.createLdapEntry(specialCharsLdapEntry3);
}
/** @throws Exception On test failure. */
@AfterClass(groups = {"auth"}, dependsOnGroups = {"authAccountState"})
public void deleteAuthEntry()
throws Exception
{
super.deleteLdapEntry(testLdapEntry.getDn());
super.deleteLdapEntry(specialCharsLdapEntry2.getDn());
super.deleteLdapEntry(specialCharsLdapEntry3.getDn());
final AuthenticationHandler ah = pooledTLSAuth.getAuthenticationHandler();
try {
(((PooledConnectionFactoryManager) ah).getConnectionFactory().getConnectionPool()).close();
} catch (IllegalStateException e) {
AssertJUnit.fail(e.getMessage());
}
}
/**
* @param createNew whether to construct a new authenticator.
*
* @return authenticator
*
* @throws Exception On authenticator construction failure.
*/
public Authenticator createTLSAuthenticator(final boolean createNew)
throws Exception
{
if (createNew) {
return TestUtils.createTLSAuthenticator();
}
return singleTLSAuth;
}
/**
* @param createNew whether to construct a new authenticator.
*
* @return authenticator
*
* @throws Exception On authenticator construction failure.
*/
public Authenticator createTLSDnAuthenticator(final boolean createNew)
throws Exception
{
if (createNew) {
return TestUtils.createTLSDnAuthenticator();
}
return singleTLSDnAuth;
}
/**
* @param createNew whether to construct a new authenticator.
*
* @return authenticator
*
* @throws Exception On authenticator construction failure.
*/
public Authenticator createSSLAuthenticator(final boolean createNew)
throws Exception
{
if (createNew) {
return TestUtils.createSSLAuthenticator();
}
return singleSSLAuth;
}
/**
* @param createNew whether to construct a new authenticator.
*
* @return authenticator
*
* @throws Exception On authenticator construction failure.
*/
public Authenticator createSSLDnAuthenticator(final boolean createNew)
throws Exception
{
if (createNew) {
return TestUtils.createSSLDnAuthenticator();
}
return singleSSLDnAuth;
}
/**
* @param ldapUrl to check
* @param baseDn to check
*/
@Parameters({ "loadPropertiesUrl", "loadPropertiesBaseDn" })
@Test(groups = {"auth"})
public void loadProperties(final String ldapUrl, final String baseDn)
{
final Authenticator auth = TestUtils.readAuthenticator("classpath:/org/ldaptive/ldap.tls.properties");
final SearchDnResolver dnResolver = (SearchDnResolver) auth.getDnResolver();
final DefaultConnectionFactory resolverCf = (DefaultConnectionFactory) dnResolver.getConnectionFactory();
AssertJUnit.assertEquals(ldapUrl, resolverCf.getConnectionConfig().getLdapUrl());
AssertJUnit.assertEquals(baseDn, ((SearchDnResolver) auth.getDnResolver()).getBaseDn());
}
/**
* @param cn to get dn for.
* @param user to get dn for.
* @param duplicateFilter for user lookups
*
* @throws Exception On test failure.
*/
@Parameters({ "getDnCn", "getDnUser", "getDnDuplicateFilter" })
@Test(groups = {"auth"})
public void resolveDn(final String cn, final String user, final String duplicateFilter)
throws Exception
{
final Authenticator auth = createTLSAuthenticator(true);
// test input
AssertJUnit.assertNull(auth.resolveDn(null));
AssertJUnit.assertNull(auth.resolveDn(new User("")));
final SearchDnResolver resolver = (SearchDnResolver) auth.getDnResolver();
// test one level searching
AssertJUnit.assertEquals(testLdapEntry.getDn().toLowerCase(), auth.resolveDn(new User(user)).toLowerCase());
// test duplicate DNs
final String filter = resolver.getUserFilter();
resolver.setUserFilter(duplicateFilter);
try {
auth.resolveDn(new User(user));
AssertJUnit.fail("Should have thrown LdapException");
} catch (Exception e) {
AssertJUnit.assertEquals(LdapException.class, e.getClass());
}
resolver.setAllowMultipleDns(true);
auth.resolveDn(new User(user));
resolver.setUserFilter(filter);
resolver.setAllowMultipleDns(false);
// test subtree searching
resolver.setSubtreeSearch(true);
final String baseDn = resolver.getBaseDn();
resolver.setBaseDn(baseDn.substring(baseDn.indexOf(",") + 1));
AssertJUnit.assertEquals(testLdapEntry.getDn().toLowerCase(), auth.resolveDn(new User(user)).toLowerCase());
}
/**
* @param cn to get dn for.
* @param user to get dn for.
* @param duplicateFilter for user lookups
*
* @throws Exception On test failure.
*/
@Parameters({ "getDnCn", "getDnUser", "getDnDuplicateFilter" })
@Test(groups = {"auth"})
public void resolveDnFormat(final String cn, final String user, final String duplicateFilter)
throws Exception
{
final Authenticator auth = createTLSAuthenticator(true);
final SearchDnResolver resolver = (SearchDnResolver) auth.getDnResolver();
auth.setDnResolver(new FormatDnResolver("cn=%s,%s", new Object[] {resolver.getBaseDn()}));
AssertJUnit.assertEquals(testLdapEntry.getDn(), auth.resolveDn(new User(cn)));
}
/**
* @param cn to get dn for.
* @param user to get dn for.
* @param duplicateFilter for user lookups
*
* @throws Exception On test failure.
*/
@Parameters({ "getDnCn", "getDnUser", "getDnDuplicateFilter" })
@Test(groups = {"auth"})
public void resolveDnVelocity(final String cn, final String user, final String duplicateFilter)
throws Exception
{
final Authenticator auth = createTLSAuthenticator(true);
final SearchDnResolver resolver = (SearchDnResolver) auth.getDnResolver();
final VelocityEngine engine = new VelocityEngine();
engine.addProperty("string.resource.loader.class",
"org.apache.velocity.runtime.resource.loader.StringResourceLoader");
engine.addProperty("resource.loader", "string");
engine.addProperty("runtime.log.logsystem.class", "org.apache.velocity.runtime.log.NullLogChute");
engine.init();
final VelocityContext context = new VelocityContext();
context.put("context", new UserContext(user));
final TemplateSearchDnResolver velocityResolver = new TemplateSearchDnResolver(
resolver.getConnectionFactory(),
engine,
"(|(uid=$context.principal)(mail=$context.principal))");
velocityResolver.setBaseDn(resolver.getBaseDn());
auth.setDnResolver(velocityResolver);
AssertJUnit.assertEquals(
testLdapEntry.getDn().toLowerCase(),
auth.resolveDn(new User(null, context)).toLowerCase());
}
/**
* @param user to get dn for.
*
* @throws Exception On test failure.
*/
@Parameters("getDnUser")
@Test(groups = {"auth"})
public void resolveDnAggregate(final String user)
throws Exception
{
final Authenticator auth = createTLSAuthenticator(true);
final SearchDnResolver sr1 = (SearchDnResolver) auth.getDnResolver();
final SearchDnResolver sr2 = new SearchDnResolver();
sr2.setAllowMultipleDns(sr1.getAllowMultipleDns());
sr2.setConnectionFactory(sr1.getConnectionFactory());
sr2.setBaseDn(sr1.getBaseDn());
sr2.setSubtreeSearch(sr1.getSubtreeSearch());
sr2.setUserFilter(sr1.getUserFilter());
sr2.setUserFilterParameters(sr1.getUserFilterParameters());
final Map<String, DnResolver> resolvers = new HashMap<>();
resolvers.put("resolver1", sr1);
resolvers.put("resolver2", sr2);
final AggregateDnResolver resolver = new AggregateDnResolver(resolvers);
auth.setDnResolver(resolver);
// test input
AssertJUnit.assertNull(auth.resolveDn(null));
AssertJUnit.assertNull(auth.resolveDn(new User("")));
// test duplicate DNs
resolver.setAllowMultipleDns(false);
try {
auth.resolveDn(new User(user));
AssertJUnit.fail("Should have thrown LdapException");
} catch (UnsupportedOperationException e) {
// ignore this test if not supported by the provider
AssertJUnit.assertNotNull(e);
} catch (Exception e) {
AssertJUnit.assertEquals(LdapException.class, e.getClass());
}
resolver.setAllowMultipleDns(true);
AssertJUnit.assertEquals(
testLdapEntry.getDn().toLowerCase(), auth.resolveDn(new User(user)).toLowerCase().split(":")[1]);
}
/**
* @param dn to authenticate.
* @param credential to authenticate with.
* @param returnAttrs to search for.
* @param ldifFile to expect from the search.
*
* @throws Exception On test failure.
*/
@Parameters(
{
"authenticateDn",
"authenticateDnCredential",
"authenticateDnReturnAttrs",
"authenticateDnResults"
})
@Test(
groups = {"auth"}, threadPoolSize = TEST_THREAD_POOL_SIZE, invocationCount = TEST_INVOCATION_COUNT,
timeOut = TEST_TIME_OUT)
public void authenticateDn(final String dn, final String credential, final String returnAttrs, final String ldifFile)
throws Exception
{
// test plain auth
final Authenticator auth = createTLSDnAuthenticator(false);
AuthenticationResponse response = auth.authenticate(new AuthenticationRequest(dn, new Credential(INVALID_PASSWD)));
AssertJUnit.assertFalse(response.getResult());
response = auth.authenticate(new AuthenticationRequest(dn, new Credential(credential)));
AssertJUnit.assertTrue(response.getResult());
// test auth with return attributes
final String expected = TestUtils.readFileIntoString(ldifFile);
response = auth.authenticate(new AuthenticationRequest(dn, new Credential(credential), returnAttrs.split("\\|")));
TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), new SearchResult(response.getLdapEntry()));
}
/**
* @param dn to authenticate.
* @param credential to authenticate with.
* @param returnAttrs to search for.
* @param ldifFile to expect from the search.
*
* @throws Exception On test failure.
*/
@Parameters(
{
"authenticateDn",
"authenticateDnCredential",
"authenticateDnReturnAttrs",
"authenticateDnResults"
})
@Test(
groups = {"auth"}, threadPoolSize = TEST_THREAD_POOL_SIZE, invocationCount = TEST_INVOCATION_COUNT,
timeOut = TEST_TIME_OUT)
public void authenticateDnSsl(
final String dn,
final String credential,
final String returnAttrs,
final String ldifFile)
throws Exception
{
// test plain auth
final Authenticator auth = createSSLDnAuthenticator(false);
AuthenticationResponse response = auth.authenticate(new AuthenticationRequest(dn, new Credential(INVALID_PASSWD)));
AssertJUnit.assertFalse(response.getResult());
response = auth.authenticate(new AuthenticationRequest(dn, new Credential(credential)));
AssertJUnit.assertTrue(response.getResult());
// test auth with return attributes
final String expected = TestUtils.readFileIntoString(ldifFile);
response = auth.authenticate(new AuthenticationRequest(dn, new Credential(credential), returnAttrs.split("\\|")));
TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), new SearchResult(response.getLdapEntry()));
}
/**
* @param dn to authenticate.
* @param credential to authenticate with.
* @param filter to authorize with.
* @param filterParameters to authorize with.
*
* @throws Exception On test failure.
*/
@Parameters(
{
"authenticateDn",
"authenticateDnCredential",
"authenticateDnFilter",
"authenticateDnFilterParameters"
})
@Test(groups = {"auth"})
public void authenticateDnHandler(
final String dn,
final String credential,
final String filter,
final String filterParameters)
throws Exception
{
final Authenticator auth = createTLSDnAuthenticator(true);
final TestAuthenticationResponseHandler authHandler = new TestAuthenticationResponseHandler();
auth.setAuthenticationResponseHandlers(authHandler);
AuthenticationResponse response = auth.authenticate(new AuthenticationRequest(dn, new Credential(INVALID_PASSWD)));
AssertJUnit.assertFalse(response.getResult());
AssertJUnit.assertTrue(!authHandler.getResults().isEmpty());
AssertJUnit.assertFalse(authHandler.getResults().get(dn));
response = auth.authenticate(new AuthenticationRequest(dn, new Credential(credential)));
AssertJUnit.assertTrue(response.getResult());
AssertJUnit.assertTrue(authHandler.getResults().get(dn));
authHandler.getResults().clear();
response = auth.authenticate(new AuthenticationRequest(dn, new Credential(credential)));
AssertJUnit.assertTrue(response.getResult());
AssertJUnit.assertTrue(authHandler.getResults().get(dn));
}
/**
* @param user to authenticate.
* @param credential to authenticate with.
*
* @throws Exception On test failure.
*/
@Parameters({ "digestMd5User", "digestMd5Credential" })
@Test(groups = {"auth"})
public void authenticateDigestMd5(final String user, final String credential)
throws Exception
{
// TODO ignore active directory until it's configured
if (TestControl.isActiveDirectory()) {
return;
}
final Authenticator auth = TestUtils.createDigestMD5Authenticator();
AuthenticationResponse response = auth.authenticate(
new AuthenticationRequest(user, new Credential(INVALID_PASSWD), ReturnAttributes.NONE.value()));
AssertJUnit.assertFalse(response.getResult());
response = auth.authenticate(
new AuthenticationRequest(user, new Credential(credential), ReturnAttributes.NONE.value()));
AssertJUnit.assertTrue(response.getResult());
}
/**
* @param user to authenticate.
* @param credential to authenticate with.
*
* @throws Exception On test failure.
*/
@Parameters({ "cramMd5User", "cramMd5Credential" })
@Test(groups = {"auth"})
public void authenticateCramMd5(final String user, final String credential)
throws Exception
{
// TODO ignore active directory until it's configured
if (TestControl.isActiveDirectory()) {
return;
}
try {
final Authenticator auth = TestUtils.createCramMD5Authenticator();
AuthenticationResponse response = auth.authenticate(
new AuthenticationRequest(user, new Credential(INVALID_PASSWD), ReturnAttributes.NONE.value()));
AssertJUnit.assertFalse(response.getResult());
response = auth.authenticate(
new AuthenticationRequest(user, new Credential(credential), ReturnAttributes.NONE.value()));
AssertJUnit.assertTrue(response.getResult());
} catch (LdapException e) {
// ignore this test if not supported by the server
AssertJUnit.assertEquals(ResultCode.AUTH_METHOD_NOT_SUPPORTED, e.getResultCode());
} catch (UnsupportedOperationException e) {
// ignore this test if not supported by the provider
AssertJUnit.assertNotNull(e);
}
}
/**
* @param user to authenticate.
* @param credential to authenticate with.
* @param returnAttrs to search for.
* @param ldifFile to expect from the search.
*
* @throws Exception On test failure.
*/
@Parameters(
{
"authenticateUser",
"authenticateCredential",
"authenticateReturnAttrs",
"authenticateResults"
})
@Test(
groups = {"auth"}, threadPoolSize = TEST_THREAD_POOL_SIZE, invocationCount = TEST_INVOCATION_COUNT,
timeOut = TEST_TIME_OUT)
public void authenticate(final String user, final String credential, final String returnAttrs, final String ldifFile)
throws Exception
{
final Authenticator auth = createTLSAuthenticator(false);
// test invalid user
AuthenticationResponse response = auth.authenticate(
new AuthenticationRequest("i-do-not-exist", new Credential(credential)));
AssertJUnit.assertFalse(response.getResult());
AssertJUnit.assertEquals(AuthenticationResultCode.DN_RESOLUTION_FAILURE, response.getAuthenticationResultCode());
AssertJUnit.assertNull(response.getResultCode());
AssertJUnit.assertNotNull(response.getMessage());
// test failed auth with return attributes
response = auth.authenticate(
new AuthenticationRequest(user, new Credential(INVALID_PASSWD), returnAttrs.split("\\|")));
AssertJUnit.assertFalse(response.getResult());
AssertJUnit.assertEquals(
AuthenticationResultCode.AUTHENTICATION_HANDLER_FAILURE,
response.getAuthenticationResultCode());
AssertJUnit.assertEquals(ResultCode.INVALID_CREDENTIALS, response.getResultCode());
response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential)));
AssertJUnit.assertTrue(response.getResult());
AssertJUnit.assertEquals(
AuthenticationResultCode.AUTHENTICATION_HANDLER_SUCCESS,
response.getAuthenticationResultCode());
AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode());
// test auth with return attributes
final String expected = TestUtils.readFileIntoString(ldifFile);
response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential), returnAttrs.split("\\|")));
AssertJUnit.assertTrue(response.getResult());
AssertJUnit.assertEquals(
AuthenticationResultCode.AUTHENTICATION_HANDLER_SUCCESS,
response.getAuthenticationResultCode());
AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode());
TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), new SearchResult(response.getLdapEntry()));
}
/**
* @param user to authenticate.
* @param credential to authenticate with.
* @param returnAttrs to search for.
* @param ldifFile to expect from the search.
*
* @throws Exception On test failure.
*/
@Parameters(
{
"authenticateUser",
"authenticateCredential",
"authenticateReturnAttrs",
"authenticateResults"
})
@Test(
groups = {"auth"}, threadPoolSize = TEST_THREAD_POOL_SIZE, invocationCount = TEST_INVOCATION_COUNT,
timeOut = TEST_TIME_OUT)
public void authenticateSsl(
final String user,
final String credential,
final String returnAttrs,
final String ldifFile)
throws Exception
{
final Authenticator auth = createSSLAuthenticator(false);
// test plain auth
AuthenticationResponse response = auth.authenticate(
new AuthenticationRequest(user, new Credential(INVALID_PASSWD)));
AssertJUnit.assertFalse(response.getResult());
response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential)));
AssertJUnit.assertTrue(response.getResult());
// test auth with return attributes
final String expected = TestUtils.readFileIntoString(ldifFile);
response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential), returnAttrs.split("\\|")));
TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), new SearchResult(response.getLdapEntry()));
}
/**
* @param user to authenticate.
* @param credential to authenticate with.
* @param filter to authorize with.
* @param returnAttrs to search for.
* @param ldifFile to expect from the search.
*
* @throws Exception On test failure.
*/
@Parameters(
{
"authenticateUser",
"authenticateCredential",
"authenticateFilter",
"authenticateReturnAttrs",
"authenticateResults"
})
@Test(
groups = {"auth"}, threadPoolSize = TEST_THREAD_POOL_SIZE, invocationCount = TEST_INVOCATION_COUNT,
timeOut = TEST_TIME_OUT)
public void authenticatePooled(
final String user,
final String credential,
final String filter,
final String returnAttrs,
final String ldifFile)
throws Exception
{
// test plain auth
AuthenticationResponse response = pooledTLSAuth.authenticate(
new AuthenticationRequest(user, new Credential(INVALID_PASSWD)));
AssertJUnit.assertFalse(response.getResult());
response = pooledTLSAuth.authenticate(new AuthenticationRequest(user, new Credential(credential)));
AssertJUnit.assertTrue(response.getResult());
// test auth with return attributes
final String expected = TestUtils.readFileIntoString(ldifFile);
response = pooledTLSAuth.authenticate(
new AuthenticationRequest(user, new Credential(credential), returnAttrs.split("\\|")));
TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), new SearchResult(response.getLdapEntry()));
}
/**
* @param user to authenticate.
* @param credential to authenticate with.
* @param filter to authorize with.
* @param returnAttrs to search for.
* @param ldifFile to expect from the search.
*
* @throws Exception On test failure.
*/
@Parameters(
{
"authenticateUser",
"authenticateCredential",
"authenticateFilter",
"authenticateReturnAttrs",
"authenticateResults"
})
@Test(groups = {"auth"})
public void authenticateVelocity(
final String user,
final String credential,
final String filter,
final String returnAttrs,
final String ldifFile)
throws Exception
{
final Authenticator auth = createTLSAuthenticator(true);
final SearchDnResolver resolver = (SearchDnResolver) auth.getDnResolver();
final VelocityEngine engine = new VelocityEngine();
engine.addProperty("string.resource.loader.class",
"org.apache.velocity.runtime.resource.loader.StringResourceLoader");
engine.addProperty("resource.loader", "string");
engine.addProperty("runtime.log.logsystem.class", "org.apache.velocity.runtime.log.NullLogChute");
engine.init();
final VelocityContext context = new VelocityContext();
context.put("context", new UserContext(user));
final TemplateSearchDnResolver velocityResolver = new TemplateSearchDnResolver(
resolver.getConnectionFactory(),
engine,
"(|(uid=$context.principal)(mail=$context.principal))");
velocityResolver.setBaseDn(resolver.getBaseDn());
auth.setDnResolver(velocityResolver);
// test plain auth
AuthenticationResponse response = auth.authenticate(
new AuthenticationRequest(new User(null, context), new Credential(INVALID_PASSWD)));
AssertJUnit.assertFalse(response.getResult());
response = auth.authenticate(new AuthenticationRequest(new User(null, context), new Credential(credential)));
AssertJUnit.assertTrue(response.getResult());
// test auth with return attributes
final String expected = TestUtils.readFileIntoString(ldifFile);
response = auth.authenticate(
new AuthenticationRequest(new User(null, context), new Credential(credential), returnAttrs.split("\\|")));
TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), new SearchResult(response.getLdapEntry()));
}
/**
* @param user to authenticate.
* @param credential to authenticate with.
* @param returnAttrs to search for.
* @param ldifFile to expect from the search.
*
* @throws Exception On test failure.
*/
@Parameters(
{
"authenticateUser",
"authenticateCredential",
"authenticateReturnAttrs",
"authenticateResults"
})
@Test(groups = {"auth"})
public void authenticateAggregate(
final String user,
final String credential,
final String returnAttrs,
final String ldifFile)
throws Exception
{
final Authenticator auth = createTLSAuthenticator(true);
final SearchDnResolver sr1 = (SearchDnResolver) auth.getDnResolver();
final SearchDnResolver sr2 = new SearchDnResolver();
sr2.setAllowMultipleDns(sr1.getAllowMultipleDns());
sr2.setConnectionFactory(sr1.getConnectionFactory());
sr2.setBaseDn(sr1.getBaseDn());
sr2.setSubtreeSearch(sr1.getSubtreeSearch());
sr2.setUserFilter(sr1.getUserFilter());
sr2.setUserFilterParameters(sr1.getUserFilterParameters());
final Map<String, DnResolver> dnResolvers = new HashMap<>();
dnResolvers.put("system1", sr1);
dnResolvers.put("system2", sr2);
final AggregateDnResolver dnResolver = new AggregateDnResolver(dnResolvers);
auth.setDnResolver(dnResolver);
final Map<String, AuthenticationHandler> authHandlers = new HashMap<>();
authHandlers.put("system1", auth.getAuthenticationHandler());
authHandlers.put("system2", auth.getAuthenticationHandler());
final AggregateDnResolver.AuthenticationHandler authHandler = new AggregateDnResolver.AuthenticationHandler();
authHandler.setAuthenticationHandlers(authHandlers);
auth.setAuthenticationHandler(authHandler);
// test invalid user
AuthenticationResponse response = auth.authenticate(
new AuthenticationRequest("i-do-not-exist", new Credential(credential)));
AssertJUnit.assertFalse(response.getResult());
AssertJUnit.assertEquals(AuthenticationResultCode.DN_RESOLUTION_FAILURE, response.getAuthenticationResultCode());
AssertJUnit.assertNull(response.getResultCode());
AssertJUnit.assertNotNull(response.getMessage());
// test multiple DNs
try {
auth.authenticate(new AuthenticationRequest(user, new Credential(INVALID_PASSWD)));
AssertJUnit.fail("Should have thrown LdapException");
} catch (Exception e) {
AssertJUnit.assertEquals(LdapException.class, e.getClass());
}
dnResolver.setAllowMultipleDns(true);
// test failed auth with return attributes
response = auth.authenticate(
new AuthenticationRequest(user, new Credential(INVALID_PASSWD), returnAttrs.split("\\|")));
AssertJUnit.assertFalse(response.getResult());
AssertJUnit.assertEquals(
AuthenticationResultCode.AUTHENTICATION_HANDLER_FAILURE,
response.getAuthenticationResultCode());
AssertJUnit.assertEquals(ResultCode.INVALID_CREDENTIALS, response.getResultCode());
response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential)));
AssertJUnit.assertTrue(response.getResult());
AssertJUnit.assertEquals(
AuthenticationResultCode.AUTHENTICATION_HANDLER_SUCCESS,
response.getAuthenticationResultCode());
AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode());
// test auth with return attributes
final String expected = TestUtils.readFileIntoString(ldifFile);
response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential), returnAttrs.split("\\|")));
AssertJUnit.assertTrue(response.getResult());
AssertJUnit.assertEquals(
AuthenticationResultCode.AUTHENTICATION_HANDLER_SUCCESS,
response.getAuthenticationResultCode());
AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode());
TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), new SearchResult(response.getLdapEntry()));
}
/**
* @param user to authenticate.
* @param credential to authenticate with.
* @param returnAttrs to search for.
*
* @throws Exception On test failure.
*/
@Parameters(
{
"authenticateUser",
"authenticateCredential",
"authenticateReturnAttrs"
})
@Test(groups = {"auth"})
public void authenticateInvalidInput(final String user, final String credential, final String returnAttrs)
throws Exception
{
final Authenticator auth = createTLSAuthenticator(true);
AuthenticationResponse response = auth.authenticate(
new AuthenticationRequest(user, null, returnAttrs.split("\\|")));
AssertJUnit.assertEquals(AuthenticationResultCode.INVALID_CREDENTIAL, response.getAuthenticationResultCode());
AssertJUnit.assertNull(response.getResultCode());
AssertJUnit.assertNotNull(response.getMessage());
response = auth.authenticate(
new AuthenticationRequest(user, new Credential(new byte[0]), returnAttrs.split("\\|")));
AssertJUnit.assertEquals(AuthenticationResultCode.INVALID_CREDENTIAL, response.getAuthenticationResultCode());
AssertJUnit.assertNull(response.getResultCode());
AssertJUnit.assertNotNull(response.getMessage());
response = auth.authenticate(new AuthenticationRequest(user, new Credential(""), returnAttrs.split("\\|")));
AssertJUnit.assertEquals(AuthenticationResultCode.INVALID_CREDENTIAL, response.getAuthenticationResultCode());
AssertJUnit.assertNull(response.getResultCode());
AssertJUnit.assertNotNull(response.getMessage());
response = auth.authenticate(
new AuthenticationRequest((String) null, new Credential(credential), returnAttrs.split("\\|")));
AssertJUnit.assertEquals(AuthenticationResultCode.DN_RESOLUTION_FAILURE, response.getAuthenticationResultCode());
AssertJUnit.assertNull(response.getResultCode());
AssertJUnit.assertNotNull(response.getMessage());
response = auth.authenticate(new AuthenticationRequest("", new Credential(credential), returnAttrs.split("\\|")));
AssertJUnit.assertEquals(AuthenticationResultCode.DN_RESOLUTION_FAILURE, response.getAuthenticationResultCode());
AssertJUnit.assertNull(response.getResultCode());
AssertJUnit.assertNotNull(response.getMessage());
}
/**
* @param user to authenticate.
* @param credential to authenticate with.
* @param returnAttrs to search for.
* @param ldifFile to expect from the search.
*
* @throws Exception On test failure.
*/
@Parameters(
{
"authenticateUser",
"authenticateCredential",
"authenticateReturnAttrs",
"authenticateResults"
})
@Test(groups = {"auth"})
public void authenticateReturnAttributes(
final String user,
final String credential,
final String returnAttrs,
final String ldifFile)
throws Exception
{
final String expected = TestUtils.readFileIntoString(ldifFile);
final Authenticator auth = createTLSAuthenticator(true);
// no attributes
AuthenticationResponse response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential)));
AssertJUnit.assertEquals(
AuthenticationResultCode.AUTHENTICATION_HANDLER_SUCCESS,
response.getAuthenticationResultCode());
AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode());
AssertJUnit.assertEquals(0, response.getLdapEntry().getAttributes().size());
// attributes on the request
response = auth.authenticate(
new AuthenticationRequest(user, new Credential(credential), returnAttrs.split("\\|")));
AssertJUnit.assertEquals(
AuthenticationResultCode.AUTHENTICATION_HANDLER_SUCCESS,
response.getAuthenticationResultCode());
AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode());
TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), new SearchResult(response.getLdapEntry()));
// attributes on the authenticator
auth.setReturnAttributes(returnAttrs.split("\\|"));
response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential)));
AssertJUnit.assertEquals(
AuthenticationResultCode.AUTHENTICATION_HANDLER_SUCCESS,
response.getAuthenticationResultCode());
AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode());
TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), new SearchResult(response.getLdapEntry()));
auth.setReturnAttributes((String) null);
// NONE attributes on the authenticator
auth.setReturnAttributes(ReturnAttributes.NONE.value());
response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential), returnAttrs.split("\\|")));
AssertJUnit.assertEquals(
AuthenticationResultCode.AUTHENTICATION_HANDLER_SUCCESS,
response.getAuthenticationResultCode());
AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode());
TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), new SearchResult(response.getLdapEntry()));
auth.setReturnAttributes((String) null);
// NONE attributes on the authenticator and request
auth.setReturnAttributes(ReturnAttributes.NONE.value());
response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential)));
AssertJUnit.assertEquals(
AuthenticationResultCode.AUTHENTICATION_HANDLER_SUCCESS,
response.getAuthenticationResultCode());
AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode());
AssertJUnit.assertEquals(0, response.getLdapEntry().getAttributes().size());
auth.setReturnAttributes((String) null);
}
/**
* @param user to authenticate.
* @param credential to authenticate with.
*
* @throws Exception On test failure.
*/
@Parameters(
{
"authenticateSpecialCharsUser2",
"authenticateSpecialCharsCredential2"
})
@Test(groups = {"auth"})
public void authenticateSpecialChars2(final String user, final String credential)
throws Exception
{
final Authenticator auth = createTLSAuthenticator(true);
// test without rewrite
AuthenticationResponse response = auth.authenticate(
new AuthenticationRequest(user, new Credential(INVALID_PASSWD)));
AssertJUnit.assertFalse(response.getResult());
response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential)));
AssertJUnit.assertTrue(response.getResult());
// test with rewrite
// TODO ignore active directory until it's configured
if (TestControl.isActiveDirectory()) {
return;
}
((SearchDnResolver) auth.getDnResolver()).setBaseDn("dc=blah");
((SearchDnResolver) auth.getDnResolver()).setSubtreeSearch(true);
response = auth.authenticate(new AuthenticationRequest(user, new Credential(INVALID_PASSWD)));
AssertJUnit.assertFalse(response.getResult());
response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential)));
AssertJUnit.assertTrue(response.getResult());
}
/**
* @param user to authenticate.
* @param credential to authenticate with.
*
* @throws Exception On test failure.
*/
@Parameters(
{
"authenticateSpecialCharsUser3",
"authenticateSpecialCharsCredential3"
})
@Test(groups = {"auth"})
public void authenticateSpecialChars3(final String user, final String credential)
throws Exception
{
final Authenticator auth = createTLSAuthenticator(true);
AuthenticationResponse response = auth.authenticate(
new AuthenticationRequest(user, new Credential(INVALID_PASSWD)));
AssertJUnit.assertFalse(response.getResult());
response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential)));
AssertJUnit.assertTrue(response.getResult());
}
/**
* @param user to authenticate.
* @param credential to authenticate with.
* @param returnAttrs to search for.
* @param ldifFile to expect from the search.
*
* @throws Exception On test failure.
*/
@Parameters(
{
"authenticateUser",
"authenticateCredential",
"authenticateReturnAttrs",
"authenticateResults"
})
@Test(
groups = {"auth"}, threadPoolSize = TEST_THREAD_POOL_SIZE, invocationCount = TEST_INVOCATION_COUNT,
timeOut = TEST_TIME_OUT)
public void authenticateSearchEntry(
final String user,
final String credential,
final String returnAttrs,
final String ldifFile)
throws Exception
{
final Authenticator auth = createTLSAuthenticator(false);
final SearchDnResolver dnResolver = (SearchDnResolver) auth.getDnResolver();
final SearchEntryResolver entryResolver = new SearchEntryResolver();
entryResolver.setUserFilter(dnResolver.getUserFilter());
entryResolver.setBaseDn(dnResolver.getBaseDn());
entryResolver.setSubtreeSearch(dnResolver.getSubtreeSearch());
auth.setEntryResolver(entryResolver);
final String expected = TestUtils.readFileIntoString(ldifFile);
final AuthenticationResponse response = auth.authenticate(
new AuthenticationRequest(user, new Credential(credential), returnAttrs.split("\\|")));
AssertJUnit.assertTrue(response.getResult());
AssertJUnit.assertEquals(
AuthenticationResultCode.AUTHENTICATION_HANDLER_SUCCESS,
response.getAuthenticationResultCode());
AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode());
TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), new SearchResult(response.getLdapEntry()));
}
/**
* @param user to authenticate.
* @param credential to authenticate with.
* @param returnAttrs to search for.
* @param ldifFile to expect from the search.
*
* @throws Exception On test failure.
*/
@Parameters(
{
"authenticateUser",
"authenticateCredential",
"authenticateReturnAttrs",
"authenticateResults"
})
@Test(groups = {"auth"})
public void authenticateWhoAmI(
final String user,
final String credential,
final String returnAttrs,
final String ldifFile)
throws Exception
{
if (TestControl.isActiveDirectory()) {
return;
}
// provider doesn't support this operation
if (TestControl.isApacheProvider()) {
throw new UnsupportedOperationException("Apache LDAP does not support this operation");
}
final Authenticator auth = createTLSAuthenticator(true);
auth.setEntryResolver(new WhoAmIEntryResolver());
final String expected = TestUtils.readFileIntoString(ldifFile);
final AuthenticationResponse response = auth.authenticate(
new AuthenticationRequest(user, new Credential(credential), returnAttrs.split("\\|")));
AssertJUnit.assertTrue(response.getResult());
AssertJUnit.assertEquals(
AuthenticationResultCode.AUTHENTICATION_HANDLER_SUCCESS,
response.getAuthenticationResultCode());
AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode());
TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), new SearchResult(response.getLdapEntry()));
}
/**
* @param user to authenticate.
* @param credential to authenticate with.
* @param returnAttrs to search for.
* @param ldifFile to expect from the search.
*
* @throws Exception On test failure.
*/
@Parameters(
{
"authenticateUser",
"authenticateCredential",
"authenticateReturnAttrs",
"authenticateResults"
})
@Test(groups = {"auth"})
public void authenticateAuthorizationIdentity(
final String user,
final String credential,
final String returnAttrs,
final String ldifFile)
throws Exception
{
// provider doesn't support this control
if (TestControl.isApacheProvider()) {
throw new UnsupportedOperationException("Apache LDAP does not support this control");
}
final Authenticator auth = createTLSAuthenticator(true);
final BindAuthenticationHandler ah = (BindAuthenticationHandler) auth.getAuthenticationHandler();
ah.setAuthenticationControls(new AuthorizationIdentityRequestControl());
auth.setEntryResolver(new AuthorizationIdentityEntryResolver());
final String expected = TestUtils.readFileIntoString(ldifFile);
try {
final AuthenticationResponse response = auth.authenticate(
new AuthenticationRequest(user, new Credential(credential), returnAttrs.split("\\|")));
AssertJUnit.assertTrue(response.getResult());
AssertJUnit.assertEquals(
AuthenticationResultCode.AUTHENTICATION_HANDLER_SUCCESS,
response.getAuthenticationResultCode());
AssertJUnit.assertEquals(ResultCode.SUCCESS, response.getResultCode());
TestUtils.assertEquals(TestUtils.convertLdifToResult(expected), new SearchResult(response.getLdapEntry()));
} catch (IllegalStateException e) {
throw new UnsupportedOperationException("LDAP server does not support this control");
}
}
/**
* @param user to authenticate.
* @param credential to authenticate with.
*
* @throws Exception On test failure.
*/
@Parameters(
{
"authenticateUser",
"authenticateCredential"
})
@AfterClass(groups = {"auth", "authAccountState"})
public void authenticatePasswordPolicy(final String user, final String credential)
throws Exception
{
if (TestControl.isActiveDirectory()) {
return;
}
final PasswordPolicyControl ppc = new PasswordPolicyControl();
AuthenticationResponse response = null;
PasswordPolicyControl ppcResponse = null;
final Authenticator auth = createTLSAuthenticator(true);
auth.setAuthenticationResponseHandlers(new PasswordPolicyAuthenticationResponseHandler());
try (Connection conn = TestUtils.createSetupConnection()) {
conn.open();
final BindAuthenticationHandler ah = (BindAuthenticationHandler) auth.getAuthenticationHandler();
ah.setAuthenticationControls(ppc);
// test bind sending ppolicy control
response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential)));
final LdapEntry entry = response.getLdapEntry();
// test bind on locked account
final ModifyOperation modify = new ModifyOperation(conn);
modify.execute(
new ModifyRequest(
entry.getDn(),
new AttributeModification(
AttributeModificationType.ADD,
new LdapAttribute("pwdAccountLockedTime", "000001010000Z"))));
response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential)));
AssertJUnit.assertFalse(response.getResult());
ppcResponse = (PasswordPolicyControl) response.getControl(PasswordPolicyControl.OID);
AssertJUnit.assertEquals(PasswordPolicyControl.Error.ACCOUNT_LOCKED, ppcResponse.getError());
AssertJUnit.assertEquals(
PasswordPolicyControl.Error.ACCOUNT_LOCKED.getCode(),
response.getAccountState().getError().getCode());
// test bind with expiration time
modify.execute(
new ModifyRequest(
entry.getDn(),
new AttributeModification(AttributeModificationType.REMOVE, new LdapAttribute("pwdAccountLockedTime"))));
response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential)));
ppcResponse = (PasswordPolicyControl) response.getControl(PasswordPolicyControl.OID);
AssertJUnit.assertTrue(ppcResponse.getTimeBeforeExpiration() > 0);
AssertJUnit.assertNotNull(response.getAccountState().getWarning().getExpiration());
} catch (UnsupportedOperationException e) {
// ignore this test if not supported
AssertJUnit.assertNotNull(e);
}
}
/**
* @param user to authenticate.
* @param credential to authenticate with.
*
* @throws Exception On test failure.
*/
@Parameters(
{
"authenticateUser",
"authenticateCredential"
})
@AfterClass(groups = {"auth", "authAccountState"})
public void authenticateActiveDirectory(final String user, final String credential)
throws Exception
{
if (!TestControl.isActiveDirectory()) {
return;
}
final Authenticator auth = createTLSAuthenticator(true);
auth.setAuthenticationResponseHandlers(new ActiveDirectoryAuthenticationResponseHandler());
auth.setResolveEntryOnFailure(true);
// success, store the entry for modify operations
// setting return attributes uses the search entry resolver
AuthenticationResponse response = auth.authenticate(
new AuthenticationRequest(user, new Credential(credential), ReturnAttributes.ALL_USER.value()));
AssertJUnit.assertTrue(response.getResult());
AssertJUnit.assertNull(response.getAccountState());
LdapEntry entry = response.getLdapEntry();
AssertJUnit.assertNotNull(entry.getAttribute("pwdLastSet"));
AssertJUnit.assertNotNull(entry.getAttribute("userAccountControl"));
// bad password
// setting return attributes uses the search entry resolver
response = auth.authenticate(
new AuthenticationRequest(user, new Credential(INVALID_PASSWD), ReturnAttributes.ALL_USER.value()));
AssertJUnit.assertFalse(response.getResult());
AssertJUnit.assertEquals(ActiveDirectoryAccountState.Error.LOGON_FAILURE, response.getAccountState().getError());
entry = response.getLdapEntry();
AssertJUnit.assertNull(entry.getAttribute("pwdLastSet"));
AssertJUnit.assertNull(entry.getAttribute("userAccountControl"));
// bad password, no return attributes
response = auth.authenticate(new AuthenticationRequest(user, new Credential(INVALID_PASSWD)));
AssertJUnit.assertFalse(response.getResult());
AssertJUnit.assertEquals(ActiveDirectoryAccountState.Error.LOGON_FAILURE, response.getAccountState().getError());
entry = response.getLdapEntry();
AssertJUnit.assertNull(entry.getAttribute("pwdLastSet"));
AssertJUnit.assertNull(entry.getAttribute("userAccountControl"));
// bad password, leverage an existing connection factory for entry
// resolution on a failed bind
final BindAuthenticationHandler ah = (BindAuthenticationHandler) singleTLSAuth.getAuthenticationHandler();
auth.setEntryResolver(new SearchEntryResolver(ah.getConnectionFactory()));
response = auth.authenticate(
new AuthenticationRequest(user, new Credential(INVALID_PASSWD), ReturnAttributes.ALL_USER.value()));
AssertJUnit.assertFalse(response.getResult());
AssertJUnit.assertEquals(ActiveDirectoryAccountState.Error.LOGON_FAILURE, response.getAccountState().getError());
entry = response.getLdapEntry();
AssertJUnit.assertNotNull(entry.getAttribute("pwdLastSet"));
AssertJUnit.assertNotNull(entry.getAttribute("userAccountControl"));
auth.setEntryResolver(null);
try (Connection conn = TestUtils.createSetupConnection()) {
conn.open();
final ModifyOperation modify = new ModifyOperation(conn);
// account disabled
final String userAccountControl = entry.getAttribute("userAccountControl").getStringValue();
modify.execute(
new ModifyRequest(
entry.getDn(),
new AttributeModification(
AttributeModificationType.REPLACE,
new LdapAttribute("userAccountControl", "514"))));
response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential)));
AssertJUnit.assertFalse(response.getResult());
AssertJUnit.assertEquals(
ActiveDirectoryAccountState.Error.ACCOUNT_DISABLED,
response.getAccountState().getError());
modify.execute(
new ModifyRequest(
entry.getDn(),
new AttributeModification(
AttributeModificationType.REPLACE,
new LdapAttribute("userAccountControl", userAccountControl))));
// account must change password
modify.execute(
new ModifyRequest(
entry.getDn(),
new AttributeModification(AttributeModificationType.REPLACE, new LdapAttribute("pwdLastSet", "0"))));
response = auth.authenticate(new AuthenticationRequest(user, new Credential(credential)));
AssertJUnit.assertFalse(response.getResult());
AssertJUnit.assertEquals(
ActiveDirectoryAccountState.Error.PASSWORD_MUST_CHANGE,
response.getAccountState().getError());
}
}
}