[java-plugin-shibd] branch dev/StateMgmtWIP updated: Bug fix and unit test for sealed state manager case.
Codeberg
noreply at shibboleth.net
Tue May 5 13:02:30 UTC 2026
This is an automated email from the git hooks/post-receive script.
codeberg pushed a commit to branch dev/StateMgmtWIP
in repository java-plugin-shibd.
View the commit online:
https://codeberg.org/Shibboleth/java-plugin-shibd/commit/1c1096293c6a3406fb739991a98187509bed46cf
The following commit(s) were added to refs/heads/dev/StateMgmtWIP by this push:
new 1c10962 Bug fix and unit test for sealed state manager case.
1c10962 is described below
commit 1c1096293c6a3406fb739991a98187509bed46cf
Author: Scott Cantor <scott at restingparrotsoftware.com>
AuthorDate: Tue May 5 09:02:14 2026 -0400
Bug fix and unit test for sealed state manager case.
---
.../sp/state/impl/CookieStateManager.java | 2 +-
.../sp/state/impl/CookieStateManagerTest.java | 94 ++++++++++++++++++----
2 files changed, 80 insertions(+), 16 deletions(-)
diff --git a/sp-server-impl/src/main/java/net/shibboleth/sp/state/impl/CookieStateManager.java b/sp-server-impl/src/main/java/net/shibboleth/sp/state/impl/CookieStateManager.java
index 29f9875..d1fef30 100644
--- a/sp-server-impl/src/main/java/net/shibboleth/sp/state/impl/CookieStateManager.java
+++ b/sp-server-impl/src/main/java/net/shibboleth/sp/state/impl/CookieStateManager.java
@@ -144,12 +144,12 @@ public class CookieStateManager extends AbstractStateManager {
} else {
try {
decoded = new String(Base64Support.decodeURLSafe(cookieValue), StandardCharsets.UTF_8);
- return decoded;
} catch (final DecodingException e) {
throw new IOException(e);
}
}
log.trace("Recovered state token mapping from '{}' to value '{}'", stateToken, decoded);
+ return decoded;
}
log.warn("No cookie found matching state token: '{}'", stateToken);
diff --git a/sp-server-impl/src/test/java/net/shibboleth/sp/state/impl/CookieStateManagerTest.java b/sp-server-impl/src/test/java/net/shibboleth/sp/state/impl/CookieStateManagerTest.java
index 0cfa75c..9352e26 100644
--- a/sp-server-impl/src/test/java/net/shibboleth/sp/state/impl/CookieStateManagerTest.java
+++ b/sp-server-impl/src/test/java/net/shibboleth/sp/state/impl/CookieStateManagerTest.java
@@ -22,11 +22,11 @@ import java.util.List;
import javax.annotation.Nonnull;
+import org.springframework.core.io.ClassPathResource;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@@ -41,8 +41,12 @@ import net.shibboleth.shared.component.ComponentInitializationException;
import net.shibboleth.shared.net.CookieManager;
import net.shibboleth.shared.net.CookieManager.SameSiteValue;
import net.shibboleth.shared.primitive.NonnullSupplier;
+import net.shibboleth.shared.resource.Resource;
+import net.shibboleth.shared.security.DataSealer;
+import net.shibboleth.shared.security.impl.BasicKeystoreKeyStrategy;
import net.shibboleth.sp.profile.impl.BaseApplicationActionTest;
import net.shibboleth.sp.state.StateData;
+import net.shibboleth.sp.testing.TestResourceConverter;
/**
* Unit tests for {@link CookieStateManager}.
@@ -57,15 +61,17 @@ public class CookieStateManagerTest extends BaseApplicationActionTest {
// Unicode character at the end of that filename...
@Nonnull @NotEmpty private static final String TEST_RESOURCE = "https://sp.example.org/secure/foo☯.cgi";
+ private Resource keystoreResource;
+ private Resource versionResource;
+
+ private DataSealer sealer;
private CookieManager cookieManager;
private CookieStateManager stateManager;
private MockHttpServletRequest request;
private MockHttpServletResponse response;
- @BeforeClass
- public void setUp() throws ComponentInitializationException {
-
+ public void setUp(final boolean sealed) throws ComponentInitializationException {
cookieManager = new CookieManager();
cookieManager.setCookiePath("/");
cookieManager.setSameSite(SameSiteValue.None);
@@ -83,30 +89,57 @@ public class CookieStateManagerTest extends BaseApplicationActionTest {
}
});
cookieManager.initialize();
-
+
stateManager = new CookieStateManager();
stateManager.setId("test");
+ if (sealed) {
+ ClassPathResource resource =
+ new ClassPathResource("/net/shibboleth/sp/profile/impl/SealerKeyStore.jks");
+ Assert.assertTrue(resource.exists());
+ keystoreResource = TestResourceConverter.of(resource);
+
+ resource =
+ new ClassPathResource("/net/shibboleth/sp/profile/impl/SealerKeyStore.kver");
+ Assert.assertTrue(resource.exists());
+ versionResource = TestResourceConverter.of(resource);
+
+ final BasicKeystoreKeyStrategy strategy = new BasicKeystoreKeyStrategy();
+ strategy.setKeyAlias("secret");
+ strategy.setKeyPassword("kpassword");
+ strategy.setKeystorePassword("password");
+ strategy.setKeystoreResource(keystoreResource);
+ strategy.setKeyVersionResource(versionResource);
+ strategy.initialize();
+
+ final DataSealer sealer = new DataSealer();
+ sealer.setKeyStrategy(strategy);
+ sealer.initialize();
+
+ stateManager.setDataSealer(sealer);
+ }
+
final ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
- stateManager.setObjectMapper(mapper);
-
+ stateManager.setObjectMapper(mapper);
stateManager.setHttpServletRequestSupplier(new NonnullSupplier<HttpServletRequest>() {
@Nonnull public HttpServletRequest get() {
assert request != null;
return request;
}
});
-
stateManager.setCookieManager(cookieManager);
-
stateManager.initialize();
}
-
+
@AfterClass
public void tearDown() {
stateManager.destroy();
cookieManager.destroy();
+ if (sealer != null) {
+ sealer.destroy();
+ }
+
}
@BeforeMethod
@@ -118,14 +151,17 @@ public class CookieStateManagerTest extends BaseApplicationActionTest {
}
@Test
- public void testMissing() throws IOException {
+ public void testMissing() throws IOException, ComponentInitializationException {
+ setUp(false);
+
request.setCookies(new Cookie(getCookieName(), "foo"));
Assert.assertNull(stateManager.recoverFromStateToken(agent, application, "foo", StateData.class));
}
@Test
- public void testPurge() throws IOException, InterruptedException {
+ public void testPurge() throws IOException, InterruptedException, ComponentInitializationException {
+ setUp(false);
final List<Cookie> cookies = new ArrayList<>(12);
for (int i = 0; i < 12; ++i) {
@@ -145,7 +181,33 @@ public class CookieStateManagerTest extends BaseApplicationActionTest {
}
@Test
- public void testSuccess() throws IOException {
+ public void testSuccessSealed() throws IOException, ComponentInitializationException {
+ setUp(true);
+
+ final StateData source = buildStateData();
+ final String token = stateManager.preserveToStateToken(agent, application, source);
+ assert token != null;
+
+ // Move token set on response to request.
+ request = new MockHttpServletRequest();
+ request.setCookies(response.getCookies());
+ response = new MockHttpServletResponse();
+
+ final StateData recovered = stateManager.recoverFromStateToken(agent, application, token, StateData.class);
+ Assert.assertEquals(source, recovered);
+
+ // Check that old token is unset.
+ final Cookie[] cookies = response.getCookies();
+ Assert.assertEquals(cookies.length, 1);
+ Assert.assertEquals(cookies[0].getName(), CookieStateManager.DEFAULT_PREFIX + '_' + "default" + '_' + token);
+ Assert.assertEquals(cookies[0].getValue(), null);
+ Assert.assertEquals(cookies[0].getMaxAge(), 0);
+ Assert.assertEquals(cookies[0].getAttribute("SameSite"), SameSiteValue.None.getValue());
+ }
+
+ @Test
+ public void testSuccess() throws IOException, ComponentInitializationException {
+ setUp(false);
final StateData source = buildStateData();
final String token = stateManager.preserveToStateToken(agent, application, source);
@@ -169,7 +231,8 @@ public class CookieStateManagerTest extends BaseApplicationActionTest {
}
@Test
- public void testSuccessWithAddress() throws IOException {
+ public void testSuccessWithAddress() throws IOException, ComponentInitializationException {
+ setUp(false);
final StateData source = buildStateData();
source.setClientAddress("192.168.1.1");
@@ -195,7 +258,8 @@ public class CookieStateManagerTest extends BaseApplicationActionTest {
}
@Test
- public void testFailureWithAddress() throws IOException {
+ public void testFailureWithAddress() throws IOException, ComponentInitializationException {
+ setUp(false);
final StateData source = buildStateData();
source.setClientAddress("192.168.1.1");
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list