diff --git a/pom.xml b/pom.xml
index 56035b5..bded430 100644
--- a/pom.xml
+++ b/pom.xml
@@ -33,6 +33,9 @@
 	<properties>
 		<site.jira.version.id>12314785</site.jira.version.id>
 		<site.javadoc.exclude>**.impl.**</site.javadoc.exclude>
+		<org.ops4j.pax.exam.version>4.13.3</org.ops4j.pax.exam.version>
+		<!-- To debug the pax process, override this with -D -->
+		<pax.vm.options>-Xmx512M</pax.vm.options>
 	</properties>
 
 	<scm>
@@ -42,6 +45,47 @@
 	  <tag>HEAD</tag>
   </scm>
 
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.servicemix.tooling</groupId>
+				<artifactId>depends-maven-plugin</artifactId>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-failsafe-plugin</artifactId>
+				<executions>
+					<execution>
+						<id>integration-test</id>
+						<phase>integration-test</phase>
+						<goals>
+							<goal>integration-test</goal>
+						</goals>
+					</execution>
+					<execution>
+						<id>verify</id>
+						<phase>integration-test</phase>
+						<goals>
+							<goal>verify</goal>
+						</goals>
+					</execution>
+				</executions>
+				<configuration>
+					<redirectTestOutputToFile>true</redirectTestOutputToFile>
+					<systemProperties>
+						<property>
+							<name>bundle.filename</name>
+							<value>${basedir}/target/${project.build.finalName}.jar</value>
+						</property>
+						<property>
+							<name>pax.vm.options</name>
+							<value>${pax.vm.options}</value>
+						</property>
+					</systemProperties>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
 
 	<dependencies>
 		<dependency>
@@ -79,6 +123,12 @@
 			<scope>provided</scope>
 		</dependency>
 		<dependency>
+			<groupId>org.apache.sling</groupId>
+			<artifactId>org.apache.sling.jcr.resource</artifactId>
+			<version>3.0.22</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
 			<groupId>org.osgi</groupId>
 			<artifactId>osgi.core</artifactId>
 		</dependency>
@@ -153,5 +203,74 @@
 			<version>1.6.4</version>
 			<scope>test</scope>
 		</dependency>
+		<dependency>
+			<groupId>org.ops4j.pax.exam</groupId>
+			<artifactId>pax-exam</artifactId>
+			<version>${org.ops4j.pax.exam.version}</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.ops4j.pax.exam</groupId>
+			<artifactId>pax-exam-cm</artifactId>
+			<version>${org.ops4j.pax.exam.version}</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.ops4j.pax.exam</groupId>
+			<artifactId>pax-exam-container-forked</artifactId>
+			<version>${org.ops4j.pax.exam.version}</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.ops4j.pax.exam</groupId>
+			<artifactId>pax-exam-junit4</artifactId>
+			<version>${org.ops4j.pax.exam.version}</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.ops4j.pax.exam</groupId>
+			<artifactId>pax-exam-link-mvn</artifactId>
+			<version>${org.ops4j.pax.exam.version}</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.sling</groupId>
+			<artifactId>org.apache.sling.testing.paxexam</artifactId>
+			<version>3.1.0</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.httpcomponents</groupId>
+			<artifactId>httpcore</artifactId>
+			<version>4.4.13</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.httpcomponents</groupId>
+			<artifactId>httpclient</artifactId>
+			<version>4.5.13</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.felix</groupId>
+			<artifactId>org.apache.felix.healthcheck.api</artifactId>
+			<version>2.0.4</version>
+			<scope>test</scope>
+		</dependency>
+	   <dependency>
+			<groupId>org.awaitility</groupId>
+			<artifactId>awaitility</artifactId>
+			<version>4.0.0</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>javax.inject</groupId>
+			<artifactId>javax.inject</artifactId>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.felix</groupId>
+			<artifactId>org.apache.felix.framework</artifactId>
+			<version>7.0.0</version>
+			<scope>test</scope>
+		</dependency>
 	</dependencies>
 </project>
diff --git a/src/main/java/org/apache/sling/auth/form/impl/FormAuthenticationHandler.java b/src/main/java/org/apache/sling/auth/form/impl/FormAuthenticationHandler.java
index e09e2d0..d00db01 100644
--- a/src/main/java/org/apache/sling/auth/form/impl/FormAuthenticationHandler.java
+++ b/src/main/java/org/apache/sling/auth/form/impl/FormAuthenticationHandler.java
@@ -48,6 +48,7 @@
 import org.apache.sling.auth.form.FormReason;
 import org.apache.sling.auth.form.impl.jaas.FormCredentials;
 import org.apache.sling.auth.form.impl.jaas.JaasHelper;
+import org.apache.sling.jcr.resource.api.JcrResourceConstants;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.component.ComponentContext;
@@ -502,8 +503,7 @@
 		final AuthenticationInfo info = new AuthenticationInfo(HttpServletRequest.FORM_AUTH, userId);
 
 		if (jaasHelper.enabled()) {
-			// JcrResourceConstants.AUTHENTICATION_INFO_CREDENTIALS
-			info.put("user.jcr.credentials", new FormCredentials(userId, authData));
+			info.put(JcrResourceConstants.AUTHENTICATION_INFO_CREDENTIALS, new FormCredentials(userId, authData));
 		} else {
 			info.put(attrCookieAuthData, authData);
 		}
@@ -512,11 +512,19 @@
 	}
 
 	private String getCookieAuthData(final AuthenticationInfo info) {
-		Object data = info.get(attrCookieAuthData);
-		if (data instanceof String) {
-			return (String) data;
+		String authData = null;
+		if (jaasHelper.enabled()) {
+			Object credentials = info.get(JcrResourceConstants.AUTHENTICATION_INFO_CREDENTIALS);
+			if (credentials instanceof Credentials) {
+				authData = getCookieAuthData((Credentials)credentials);
+			}
+		} else {
+			Object data = info.get(attrCookieAuthData);
+			if (data instanceof String) {
+				authData = (String) data;
+			}
 		}
-		return null;
+		return authData;
 	}
 
 	// ---------- LoginModulePlugin support
diff --git a/src/test/java/org/apache/sling/auth/form/it/AuthFormTestSupport.java b/src/test/java/org/apache/sling/auth/form/it/AuthFormTestSupport.java
new file mode 100644
index 0000000..a41b7c2
--- /dev/null
+++ b/src/test/java/org/apache/sling/auth/form/it/AuthFormTestSupport.java
@@ -0,0 +1,251 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.auth.form.it;
+
+import static org.apache.felix.hc.api.FormattingResultLog.msHumanReadable;
+import static org.apache.sling.testing.paxexam.SlingOptions.awaitility;
+import static org.apache.sling.testing.paxexam.SlingOptions.slingQuickstartOakTar;
+import static org.apache.sling.testing.paxexam.SlingOptions.versionResolver;
+import static org.awaitility.Awaitility.await;
+import static org.junit.Assert.assertNotNull;
+import static org.ops4j.pax.exam.CoreOptions.composite;
+import static org.ops4j.pax.exam.CoreOptions.junitBundles;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.streamBundle;
+import static org.ops4j.pax.exam.CoreOptions.vmOption;
+import static org.ops4j.pax.exam.cm.ConfigurationAdminOptions.factoryConfiguration;
+import static org.ops4j.pax.tinybundles.core.TinyBundles.withBnd;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.text.SimpleDateFormat;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Inject;
+
+import org.apache.felix.hc.api.Result;
+import org.apache.felix.hc.api.ResultLog;
+import org.apache.felix.hc.api.execution.HealthCheckExecutionResult;
+import org.apache.felix.hc.api.execution.HealthCheckExecutor;
+import org.apache.felix.hc.api.execution.HealthCheckSelector;
+import org.apache.sling.testing.paxexam.TestSupport;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.options.ModifiableCompositeOption;
+import org.ops4j.pax.exam.options.extra.VMOption;
+import org.ops4j.pax.tinybundles.core.TinyBundle;
+import org.ops4j.pax.tinybundles.core.TinyBundles;
+import org.osgi.framework.Constants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class AuthFormTestSupport extends TestSupport {
+    private static final String BUNDLE_SYMBOLICNAME = "TEST-CONTENT-BUNDLE";
+    private static final String SLING_BUNDLE_RESOURCES_HEADER = "Sling-Bundle-Resources";
+
+    protected static final String FORM_AUTH_VERIFY_USER = "form-auth-user";
+    protected static final String FORM_AUTH_VERIFY_PWD = "testing";
+
+    protected final Logger logger = LoggerFactory.getLogger(getClass());
+
+    @Inject
+    private HealthCheckExecutor hcExecutor;
+
+
+    @Configuration
+    public Option[] configuration() throws IOException {
+        return options(
+            composite(
+                super.baseConfiguration(),
+                vmOption(System.getProperty("pax.vm.options")),
+                optionalRemoteDebug(),
+                slingQuickstart(),
+                testBundle("bundle.filename"),
+                // testing - add a user to use to login and verify the content loading has happened
+                factoryConfiguration("org.apache.sling.jcr.repoinit.RepositoryInitializer")
+                    .put("scripts", new String[] {
+                            "create user " + FORM_AUTH_VERIFY_USER + " with password " + FORM_AUTH_VERIFY_PWD +"\n"
+                            })
+                    .asOption(),
+                junitBundles(),
+                awaitility()
+            ).add(
+                additionalOptions()
+            ).remove(
+                // remove our bundle under test to avoid duplication
+                mavenBundle().groupId("org.apache.sling").artifactId("org.apache.sling.auth.form").version(versionResolver)
+            )
+        );
+    }
+
+    protected Option[] additionalOptions() throws IOException {
+        return new Option[]{};
+    }
+
+    protected Option slingQuickstart() {
+        final String workingDirectory = workingDirectory();
+        final int httpPort = findFreePort();
+        return composite(
+            slingQuickstartOakTar(workingDirectory, httpPort)
+        );
+    }
+
+    public String getTestFileUrl(String path) {
+        return getClass().getResource(path).toExternalForm();
+    }
+
+    /**
+     * Optionally configure remote debugging on the port supplied by the "debugPort"
+     * system property.
+     */
+    protected ModifiableCompositeOption optionalRemoteDebug() {
+        VMOption option = null;
+        String property = System.getProperty("debugPort");
+        if (property != null) {
+            option = vmOption(String.format("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=%s", property));
+        }
+        return composite(option);
+    }
+
+    /**
+     * Wait for the health check to be ok
+     * 
+     * @param timeoutMsec the max time to wait for the health check to be ok
+     * @param nextIterationDelay the sleep time between the check attempts
+     */
+    protected void waitForServerReady(long timeoutMsec, long nextIterationDelay) {
+        // retry until the exec call returns true and doesn't throw any exception
+        await().atMost(timeoutMsec, TimeUnit.MILLISECONDS)
+                .pollInterval(nextIterationDelay, TimeUnit.MILLISECONDS)
+                .until(this::doHealthCheck); 
+    }
+
+    /**
+     * @return true if health checks are ok
+     */
+    protected boolean doHealthCheck() throws IOException {
+        boolean isOk = true;
+        logger.info("Performing health check");
+        HealthCheckSelector hcs = HealthCheckSelector.tags("systemalive");
+        List<HealthCheckExecutionResult> results = hcExecutor.execute(hcs);
+        logger.info("systemalive health check got {} results", results.size());
+        isOk &= !results.isEmpty();
+        for (final HealthCheckExecutionResult exR : results) {
+            final Result r = exR.getHealthCheckResult();
+            if (logger.isInfoEnabled()) {
+                logger.info("systemalive health check: {}", toHealthCheckResultInfo(exR, false));
+            }
+            isOk &= r.isOk();
+            if (!isOk) {
+                break; // found a failure so stop checking further
+            }
+        }
+
+        if (isOk) {
+            hcs = HealthCheckSelector.tags("bundles");
+            results = hcExecutor.execute(hcs);
+            logger.info("bundles health check got {} results", results.size());
+            isOk &= !results.isEmpty();
+            for (final HealthCheckExecutionResult exR : results) {
+                final Result r = exR.getHealthCheckResult();
+                if (logger.isInfoEnabled()) {
+                    logger.info("bundles health check: {}", toHealthCheckResultInfo(exR, false));
+                }
+                isOk &= r.isOk();
+                if (!isOk) {
+                    break; // found a failure so stop checking further
+                }
+            }
+        }
+        return isOk;
+    }
+
+    /**
+     * Produce a human readable report of the health check results that is suitable for
+     * debugging or writing to a log
+     */
+    protected String toHealthCheckResultInfo(final HealthCheckExecutionResult exResult, final boolean debug)  throws IOException {
+        String value = null;
+        try (StringWriter resultWriter = new StringWriter(); BufferedWriter writer = new BufferedWriter(resultWriter)) {
+            final Result result = exResult.getHealthCheckResult();
+
+            writer.append('"').append(exResult.getHealthCheckMetadata().getTitle()).append('"');
+            writer.append(" result is: ").append(result.getStatus().toString());
+            writer.newLine();
+            writer.append("   Finished: ").append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(exResult.getFinishedAt()) + " after "
+                    + msHumanReadable(exResult.getElapsedTimeInMs()));
+
+            for (final ResultLog.Entry e : result) {
+                if (!debug && e.isDebug()) {
+                    continue;
+                }
+                writer.newLine();
+                writer.append("   ");
+                writer.append(e.getStatus().toString());
+                writer.append(' ');
+                writer.append(e.getMessage());
+                if (e.getException() != null) {
+                    writer.append(" ");
+                    writer.append(e.getException().toString());
+                }
+            }
+            writer.flush();
+            value = resultWriter.toString();
+        }
+        return value;
+    }
+
+    /**
+     * Add content to our test bundle
+     */
+    protected void addContent(final TinyBundle bundle, String resourcePath) throws IOException {
+        String pathInBundle = resourcePath;
+        resourcePath = "/content" + resourcePath;
+        try (final InputStream is = getClass().getResourceAsStream(resourcePath)) {
+            assertNotNull("Expecting resource to be found:" + resourcePath, is);
+            logger.info("Adding resource to bundle, path={}, resource={}", pathInBundle, resourcePath);
+            bundle.add(pathInBundle, is);
+        }
+    }
+
+    /**
+     * Build a test bundle containing the specified bundle resources
+     * 
+     * @param header the value for the {@link #SLING_BUNDLE_RESOURCES_HEADER} header
+     * @param content the collection of files to embed in the tinybundle
+     * @return the tinybundle Option
+     */
+    protected Option buildBundleResourcesBundle(final String header, final Collection<String> content) throws IOException {
+        final TinyBundle bundle = TinyBundles.bundle();
+        bundle.set(Constants.BUNDLE_SYMBOLICNAME, BUNDLE_SYMBOLICNAME);
+        bundle.set(SLING_BUNDLE_RESOURCES_HEADER, header);
+        bundle.set("Require-Capability", "osgi.extender;filter:=\"(&(osgi.extender=org.apache.sling.bundleresource)(version<=1.1.0)(!(version>=2.0.0)))\"");
+
+        for (final String entry : content) {
+            addContent(bundle, entry);
+        }
+        return streamBundle(
+            bundle.build(withBnd())
+        ).start();
+    }
+
+}
diff --git a/src/test/java/org/apache/sling/auth/form/it/SLING10290IT.java b/src/test/java/org/apache/sling/auth/form/it/SLING10290IT.java
new file mode 100644
index 0000000..c4561a4
--- /dev/null
+++ b/src/test/java/org/apache/sling/auth/form/it/SLING10290IT.java
@@ -0,0 +1,369 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.auth.form.it;
+
+import static org.apache.sling.testing.paxexam.SlingOptions.slingScriptingSightly;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.ops4j.pax.exam.cm.ConfigurationAdminOptions.factoryConfiguration;
+import static org.ops4j.pax.exam.cm.ConfigurationAdminOptions.newConfiguration;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Dictionary;
+import java.util.List;
+
+import javax.inject.Inject;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.http.Header;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.cookie.Cookie;
+import org.apache.http.cookie.CookieOrigin;
+import org.apache.http.cookie.CookieSpec;
+import org.apache.http.cookie.MalformedCookieException;
+import org.apache.http.impl.client.BasicCookieStore;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.impl.cookie.DefaultCookieSpec;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+/**
+ * integration tests to verify fix for SLING-10290
+ */
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class SLING10290IT extends AuthFormTestSupport {
+
+    @Inject
+    private ConfigurationAdmin cm;
+
+    private static final String COOKIE_SLING_FORMAUTH = "sling.formauth";
+    private static final String HEADER_SET_COOKIE = "Set-Cookie";
+
+    private URI baseServerUri;
+    private HttpClientContext httpContext;
+    private CloseableHttpClient httpClient;
+
+    @Override
+    protected Option[] additionalOptions() throws IOException {
+        // create a tinybundle that contains a test script
+        final List<String> resourcePaths = Arrays.asList("/apps/sling/OrderedFolder/SLING10290IT.html");
+        final String bundleResourcesHeader = String.join(",", resourcePaths);
+        final Option bundle = buildBundleResourcesBundle(bundleResourcesHeader, resourcePaths);
+
+        return new Option[]{
+            // add sightly support for the test script
+            slingScriptingSightly(),
+
+            // add the test script tinybundle
+            bundle,
+
+            // change the formauth timeout to 1 minute so we don't have to wait a long
+            //   time for the testRefreshCookieOnRequestAfterHalfExpirationDuration test
+            newConfiguration("org.apache.sling.auth.form.FormAuthenticationHandler")
+                .put("form.auth.timeout", "1")
+            .asOption(),
+
+            // enable the healthcheck configuration for checking when the server is ready to
+            //  receive http requests.  (adapted from the starter healthcheck.json configuration)
+            factoryConfiguration("org.apache.felix.hc.generalchecks.FrameworkStartCheck")
+                .put("hc.tags", new String[] {"systemalive"})
+                .put("targetStartLevel", 5)
+                .asOption(),
+            factoryConfiguration("org.apache.felix.hc.generalchecks.ServicesCheck")
+                .put("hc.tags", new String[] {"systemalive"})
+                .put("services.list", new String[] {
+                        "org.apache.sling.jcr.api.SlingRepository",
+                        "org.apache.sling.engine.auth.Authenticator",
+                        "org.apache.sling.api.resource.ResourceResolverFactory",
+                        "org.apache.sling.api.servlets.ServletResolver",
+                        "javax.script.ScriptEngineManager"
+                })
+                .asOption(),
+            factoryConfiguration("org.apache.felix.hc.generalchecks.BundlesStartedCheck")
+                .put("hc.tags", new String[] {"bundles"})
+                .asOption(),
+            factoryConfiguration("org.apache.sling.jcr.contentloader.hc.BundleContentLoadedCheck")
+                .put("hc.tags", new String[] {"bundles"})
+                .asOption(),
+        };
+    }
+
+    @Before
+    public void before() throws IOException, URISyntaxException {
+        // wait for the health checks to be OK
+        waitForServerReady(Duration.ofMinutes(1).toMillis(), 500);
+
+        // calculate the address of the http server
+        baseServerUri = getBaseServerUri();
+        assertNotNull(baseServerUri);
+
+        // prepare the http client for the test user
+        httpContext = HttpClientContext.create();
+        httpContext.setCookieStore(new BasicCookieStore());
+        httpClient = HttpClients.custom()
+                .disableRedirectHandling()
+                .build();
+    }
+
+    @After
+    public void after() throws IOException {
+        // close/cleanup the test user http client
+        if (httpClient != null) {
+            httpClient.close();
+            httpClient = null;
+        }
+
+        // clear out other state
+        httpContext = null;
+        baseServerUri = null;
+    }
+
+    /**
+     * Verify that the formauth cookie is sent appropriately after login
+     */
+    @Test
+    public void testSetCookieOnFirstRequestAfterLogin() throws MalformedCookieException, IOException {
+        doFormsLogin();
+    }
+
+    /**
+     * Verify that the formauth cookie is not re-sent on each request after login
+     */
+    @Test
+    public void testNoSetCookieOnSecondRequestAfterLogin() throws MalformedCookieException, IOException {
+        // 1. login as the test user
+        doFormsLogin();
+
+        // 2. do another request
+        HttpGet request = new HttpGet(whoamiUri());
+        try (CloseableHttpResponse response = httpClient.execute(request, httpContext)) {
+            assertEquals(HttpServletResponse.SC_OK, response.getStatusLine().getStatusCode());
+            Cookie parsedFormauthCookie = parseFormAuthCookieFromHeaders(response);
+            assertNull("Did not expect a formauth cookie in the response", parsedFormauthCookie);
+        }
+    }
+
+    /**
+     * Verify that the formauth cookie is refreshed on the first request after half the session duration
+     * has occurred
+     */
+    @Test
+    public void testRefreshCookieOnRequestAfterHalfExpirationDuration() throws InterruptedException, MalformedCookieException, IOException {
+        // 1. login as the test user
+        doFormsLogin();
+
+        // 2. wait for half the session timeout expiration duration
+        Thread.sleep((Duration.ofMinutes(1).toMillis() / 2) + 1); // NOSONAR
+
+        // 3. do another request to trigger the cookie refresh
+        HttpGet request = new HttpGet(whoamiUri());
+        try (CloseableHttpResponse response = httpClient.execute(request, httpContext)) {
+            assertEquals(HttpServletResponse.SC_OK, response.getStatusLine().getStatusCode());
+            Cookie parsedFormauthCookie = parseFormAuthCookieFromHeaders(response);
+            assertNotNull("Expected a refreshed formauth cookie in the response", parsedFormauthCookie);
+        }
+
+        // 4. do another request to verify that subsequent request after
+        //    the cookie refresh do not send an additional formauth cookie
+        try (CloseableHttpResponse response = httpClient.execute(request, httpContext)) {
+            assertEquals(HttpServletResponse.SC_OK, response.getStatusLine().getStatusCode());
+            Cookie parsedFormauthCookie2 = parseFormAuthCookieFromHeaders(response);
+            assertNull("Did not expect a formauth cookie in the response", parsedFormauthCookie2);
+        }
+    }
+
+    /**
+     * Calculate the base server URI from the current configuration of the
+     * httpservice
+     */
+    private URI getBaseServerUri() throws IOException, URISyntaxException {
+        assertNotNull(cm);
+        Configuration httpServiceConfiguration = cm.getConfiguration("org.apache.felix.http");
+        Dictionary<String, Object> properties = httpServiceConfiguration.getProperties();
+
+        String host;
+        Object hostObj = properties.get("org.apache.felix.http.host");
+        if (hostObj == null) {
+            host = "localhost";
+        } else {
+            assertTrue(hostObj instanceof String);
+            host = (String)hostObj;
+        }
+        assertNotNull(host);
+
+        String scheme = null;
+        Object portObj = null;
+        Object httpsEnableObj = properties.get("org.apache.felix.https.enable");
+        if ("true".equals(httpsEnableObj)) {
+            scheme = "https";
+            portObj = properties.get("org.osgi.service.http.port.secure");
+        } else {
+            Object httpEnableObj = properties.get("org.apache.felix.http.enable");
+            if (httpEnableObj == null || "true".equals(httpEnableObj)) {
+                scheme = "http";
+                portObj = properties.get("org.osgi.service.http.port");
+            } else {
+                fail("Expected either http or https to be enabled");
+            }
+        }
+        int port = -1;
+        if (portObj instanceof Number) {
+            port = ((Number)portObj).intValue();
+        }
+        assertTrue(port > 0);
+
+        return new URI(String.format("%s://%s:%d", scheme, host, port));
+    }
+
+    /**
+     * @return the address of the whoami script
+     */
+    private String whoamiUri() {
+        return String.format("%s/content.SLING10290IT.html", baseServerUri);
+    }
+
+    /**
+     * Perform the http calls to login the test user via the forms based login
+     */
+    private void doFormsLogin() throws MalformedCookieException, IOException {
+        // before login, there should be no formauth cookie in the cookie store
+        Cookie formauthCookie = getFormAuthCookieFromCookieStore();
+        assertNull("Did not expect formauth cookie in the cookie store", formauthCookie);
+
+        // verify that the script shows us as not logged in
+        HttpGet whoamiRequest = new HttpGet(whoamiUri());
+        try (CloseableHttpResponse whoamiResponse = httpClient.execute(whoamiRequest, httpContext)) {
+            assertEquals(HttpServletResponse.SC_OK, whoamiResponse.getStatusLine().getStatusCode());
+            String content = EntityUtils.toString(whoamiResponse.getEntity());
+            assertTrue(content.contains("whoAmI"));
+            assertTrue(content.contains("anonymous"));
+        }
+
+        // send the form login request
+        List<NameValuePair> parameters = new ArrayList<>();
+        parameters.add(new BasicNameValuePair("j_username", FORM_AUTH_VERIFY_USER));
+        parameters.add(new BasicNameValuePair("j_password", FORM_AUTH_VERIFY_PWD));
+        parameters.add(new BasicNameValuePair("_charset_", StandardCharsets.UTF_8.name()));
+        parameters.add(new BasicNameValuePair("resource", "/content.SLING10290IT.html"));
+        HttpPost request = new HttpPost(String.format("%s/j_security_check", baseServerUri));
+        request.setEntity(new UrlEncodedFormEntity(parameters));
+        Header locationHeader = null; 
+        try (CloseableHttpResponse response = httpClient.execute(request, httpContext)) {
+            assertEquals(HttpServletResponse.SC_MOVED_TEMPORARILY, response.getStatusLine().getStatusCode());
+            locationHeader = response.getFirstHeader("Location");
+
+            // verify that the expected set-cookie header arrived
+            Cookie parsedFormauthCookie = parseFormAuthCookieFromHeaders(response);
+            assertNotNull("Expected a formauth cookie in the response", parsedFormauthCookie);
+        }
+
+        // after login, there should be now be a cookie in the cookie store
+        Cookie formauthCookie2 = getFormAuthCookieFromCookieStore();
+        assertNotNull("Expected a formauth cookie in the cookie store", formauthCookie2);
+
+        // and then follow the redirect
+        assertNotNull("Expected a 'Location' header", locationHeader);
+        // verify that the script shows us logged in as the test user
+        HttpGet followedRequest = new HttpGet(locationHeader.getValue());
+        try (CloseableHttpResponse followedResponse = httpClient.execute(followedRequest, httpContext)) {
+            assertEquals(HttpServletResponse.SC_OK, followedResponse.getStatusLine().getStatusCode());
+            String content = EntityUtils.toString(followedResponse.getEntity());
+            assertTrue(content.contains("whoAmI"));
+            assertTrue(content.contains(FORM_AUTH_VERIFY_USER));
+
+            // there should be no new formauth cookie on the followed response
+            Cookie parsedFormauthCookie2 = parseFormAuthCookieFromHeaders(followedResponse);
+            assertNull("Did not expect a formauth cookie in the response", parsedFormauthCookie2);
+        }
+    }
+
+    /**
+     * Retrieve the formauth cookie from the cookie store
+     * 
+     * @return the formauth cookie or null if not found
+     */
+    private Cookie getFormAuthCookieFromCookieStore() {
+        Cookie formauthCookie = null;
+        List<Cookie> cookies = httpContext.getCookieStore().getCookies();
+        if (cookies != null) {
+            for (Cookie c : cookies) {
+                if (COOKIE_SLING_FORMAUTH.equals(c.getName())) {
+                    formauthCookie = c;
+                }
+            }
+        }
+        return formauthCookie;
+    }
+
+    /**
+     * Parse the formauth cookie out of the headers sent on the response
+     *
+     * @param response the response from the http request
+     * @return the found cookie or null if not found
+     */
+    private Cookie parseFormAuthCookieFromHeaders(HttpResponse response) throws MalformedCookieException {
+        Header [] cookieHeaders = response.getHeaders(HEADER_SET_COOKIE);
+        assertNotNull(cookieHeaders);
+
+        Cookie parsedFormauthCookie = null;
+        CookieSpec cookieSpec = new DefaultCookieSpec();
+        CookieOrigin origin = new CookieOrigin(baseServerUri.getHost(), baseServerUri.getPort(),
+                baseServerUri.getPath(), "https".equals(baseServerUri.getScheme()));
+        for (Header cookieHeader : cookieHeaders) {
+            List<Cookie> parsedCookies = cookieSpec.parse(cookieHeader, origin);
+            for (Cookie c : parsedCookies) {
+                if (COOKIE_SLING_FORMAUTH.equals(c.getName())) {
+                    if (parsedFormauthCookie != null) {
+                        fail(String.format("Did not expect more than one %s cookie", c.getName()));
+                    }
+                    parsedFormauthCookie = c;
+                }
+            }
+        }
+        return parsedFormauthCookie;
+    }
+
+}
diff --git a/src/test/resources/content/apps/sling/OrderedFolder/SLING10290IT.html b/src/test/resources/content/apps/sling/OrderedFolder/SLING10290IT.html
new file mode 100644
index 0000000..1d0402d
--- /dev/null
+++ b/src/test/resources/content/apps/sling/OrderedFolder/SLING10290IT.html
@@ -0,0 +1,26 @@
+<!--/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/--><!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="utf-8">
+  <title>Who Am I?</title>
+</head>
+<body>
+  <p> whoAmI: ${request.remoteUser == null ? "anonymous" : request.remoteUser}</p>
+</body>
+</html>
\ No newline at end of file
