[java-plugin-shibd] branch main updated: Adjust behavior of various operations.
Codeberg
noreply at shibboleth.net
Wed Dec 10 02:52:37 UTC 2025
This is an automated email from the git hooks/post-receive script.
codeberg pushed a commit to branch main
in repository java-plugin-shibd.
View the commit online:
https://codeberg.org/Shibboleth/java-plugin-shibd/commit/f36bfc53a96fce018f2ecff54a7b2d2df2477897
The following commit(s) were added to refs/heads/main by this push:
new f36bfc5 Adjust behavior of various operations.
f36bfc5 is described below
commit f36bfc53a96fce018f2ecff54a7b2d2df2477897
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Dec 9 21:52:26 2025 -0500
Adjust behavior of various operations.
---
.../sp/profile/impl/DoSessionCacheOperation.java | 96 +++++++++++++---------
1 file changed, 58 insertions(+), 38 deletions(-)
diff --git a/sp-server-impl/src/main/java/net/shibboleth/sp/profile/impl/DoSessionCacheOperation.java b/sp-server-impl/src/main/java/net/shibboleth/sp/profile/impl/DoSessionCacheOperation.java
index fe84111..fc64beb 100644
--- a/sp-server-impl/src/main/java/net/shibboleth/sp/profile/impl/DoSessionCacheOperation.java
+++ b/sp-server-impl/src/main/java/net/shibboleth/sp/profile/impl/DoSessionCacheOperation.java
@@ -17,7 +17,6 @@ package net.shibboleth.sp.profile.impl;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.Instant;
@@ -35,6 +34,9 @@ import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
import net.shibboleth.shared.annotation.constraint.NotEmpty;
import net.shibboleth.shared.annotation.constraint.Positive;
+import net.shibboleth.shared.codec.Base64Support;
+import net.shibboleth.shared.codec.DecodingException;
+import net.shibboleth.shared.codec.EncodingException;
import net.shibboleth.shared.component.ComponentInitializationException;
import net.shibboleth.shared.logic.Constraint;
import net.shibboleth.shared.primitive.LoggerFactory;
@@ -53,8 +55,11 @@ import net.shibboleth.sp.profile.AbstractAgentAction;
* @event {@link EventIds#INVALID_PROFILE_CTX}
* @event {@link EventIds#INVALID_MESSAGE}
* @event {@link EventIds#IO_ERROR}
+ * @event {@link EventIds#UNABLE_TO_DECODE}
+ * @event {@link EventIds#UNABLE_TO_ENCODE}
* @event {@link EventIds#MESSAGE_PROC_ERROR}
* @event {@link #INVALID_SESSION}
+ * @event {@link #MISSING_SESSION}
* @event {@link #EXPIRED_SESSION}
* @event {@link #VERSION_MISMATCH}
*/
@@ -66,6 +71,9 @@ public class DoSessionCacheOperation extends AbstractAgentAction {
/** Custom event for invalid session. */
@Nonnull @NotEmpty public static final String INVALID_SESSION = "InvalidSession";
+ /** Custom event for invalid session. */
+ @Nonnull @NotEmpty public static final String MISSING_SESSION = "MissingSession";
+
/** Custom event for expired session. */
@Nonnull @NotEmpty public static final String EXPIRED_SESSION = "ExpiredSession";
@@ -236,15 +244,18 @@ public class DoSessionCacheOperation extends AbstractAgentAction {
Long exp = Instant.now().plusSeconds(getStorageTimeout()).toEpochMilli();
- // TODO: Encode/encrypt/etc.?
String value;
try (final ByteArrayOutputStream sink = new ByteArrayOutputStream()) {
data.serialize(sink);
- value = sink.toString(StandardCharsets.UTF_8);
+ value = Base64Support.encode(sink.toByteArray(), false);
+ } catch (final EncodingException e) {
+ log.error("{} Unable to base64-encode session data", getLogPrefix(), e);
+ ActionSupport.buildEvent(profileRequestContext, EventIds.UNABLE_TO_ENCODE);
+ return;
}
- assert value != null;
-
+ // TODO: Encrypt?
+
int attempts = 0;
do {
final String key = identifierStrategy.generateIdentifier(false);
@@ -321,12 +332,15 @@ public class DoSessionCacheOperation extends AbstractAgentAction {
DDF sessionData;
try (final ByteArrayInputStream source =
- new ByteArrayInputStream(record.getValue().getBytes(StandardCharsets.UTF_8))) {
+ new ByteArrayInputStream(Base64Support.decode(record.getValue()))) {
sessionData = DDF.deserialize(source);
+ } catch (final DecodingException e) {
+ log.error("{} Unable to base64-decode session data", getLogPrefix(), e);
+ ActionSupport.buildEvent(profileRequestContext, INVALID_SESSION);
+ return;
}
- assert sessionData != null;
- // We have a deserialized session, need to enforce policies if specified.
+ // We have a deserialized session, need to enforce lifetime if specified.
final Integer lifetime = input.getmember(LIFETIME).integer();
if (lifetime != null && lifetime > 0) {
@@ -388,14 +402,17 @@ public class DoSessionCacheOperation extends AbstractAgentAction {
final Long st = getStorageTimeout();
final Long exp = Instant.now().plusSeconds(st).toEpochMilli();
- // TODO: Encode/encrypt/etc.?
String value;
try (final ByteArrayOutputStream sink = new ByteArrayOutputStream()) {
data.serialize(sink);
- value = sink.toString(StandardCharsets.UTF_8);
+ value = Base64Support.encode(sink.toByteArray(), false);
+ } catch (final EncodingException e) {
+ log.error("{} Unable to base64-encode session data", getLogPrefix(), e);
+ ActionSupport.buildEvent(profileRequestContext, EventIds.UNABLE_TO_ENCODE);
+ return;
}
-
- assert value != null;
+
+ // TODO: Encrypt?
try {
version = storageService.updateWithVersion(version, STORAGE_CONTEXT, ensureAgent().getId() + '!' + key,
@@ -433,7 +450,7 @@ public class DoSessionCacheOperation extends AbstractAgentAction {
// "timeout" - session timeout policy to apply
// Output:
- // "ver" - current version, indicates record was found and updated
+ // None
final String key = input.getmember(KEY).string();
if (key == null) {
@@ -441,30 +458,30 @@ public class DoSessionCacheOperation extends AbstractAgentAction {
ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MESSAGE);
return;
}
-
- // Read back record to check for timeout.
-
- final StorageRecord<?> record = storageService.read(STORAGE_CONTEXT, ensureAgent().getId() + '!' + key);
- if (record == null) {
- // Send back an empty response.
- log.debug("{} No session found ({})", getLogPrefix(), key);
- final DDF output = new DDF();
- ensureAgentRequestContext().setOutput(output);
- return;
- }
-
- Long lastAccess = record.getExpiration();
- if (lastAccess == null) {
- log.error("{} Session record ({}) had no expiration", getLogPrefix(), key);
- ActionSupport.buildEvent(profileRequestContext, INVALID_SESSION);
- return;
- }
-
- final Long st = getStorageTimeout();
+
final Instant now = Instant.now();
+ final Long st = getStorageTimeout();
final Integer timeout = input.getmember(TIMEOUT).integer();
if (timeout != null && timeout > 0) {
+ // Read back record to check for timeout.
+ final StorageRecord<?> record = storageService.read(STORAGE_CONTEXT, ensureAgent().getId() + '!' + key);
+ if (record == null) {
+ // Send back an empty response.
+ log.debug("{} No session found ({})", getLogPrefix(), key);
+ final DDF output = new DDF();
+ ensureAgentRequestContext().setOutput(output);
+ return;
+ }
+
+ Long lastAccess = record.getExpiration();
+ if (lastAccess == null) {
+ log.error("{} Session record ({}) had no expiration", getLogPrefix(), key);
+ ActionSupport.buildEvent(profileRequestContext, INVALID_SESSION);
+ return;
+ }
+
+
// Recover last access time by backdating record expiration.
lastAccess -= st;
if (Instant.ofEpochMilli(lastAccess).plusSeconds(timeout).isBefore(now)) {
@@ -481,14 +498,13 @@ public class DoSessionCacheOperation extends AbstractAgentAction {
if (storageService.updateExpiration(STORAGE_CONTEXT, ensureAgent().getId() + '!' + key,
now.plusSeconds(st).toEpochMilli())) {
final DDF output = new DDF();
- output.addmember(VERSION).longinteger(record.getVersion());
+ output.addmember(KEY).string(key);
ensureAgentRequestContext().setOutput(output);
} else {
// Record disappeared, so send back an empty response.
log.debug("{} Session record ({}) disappeared before update?", getLogPrefix(), key);
- final DDF output = new DDF();
- ensureAgentRequestContext().setOutput(output);
- }
+ ActionSupport.buildEvent(profileRequestContext, MISSING_SESSION);
+ }
}
/**
@@ -503,7 +519,8 @@ public class DoSessionCacheOperation extends AbstractAgentAction {
// Input:
// "key" - session key to delete
- // Output: None
+ // Output:
+ // "key" - session key, indicates record was found and deleted
final String key = input.getmember(KEY).string();
if (key == null) {
@@ -514,8 +531,11 @@ public class DoSessionCacheOperation extends AbstractAgentAction {
if (storageService.delete(STORAGE_CONTEXT, ensureAgent().getId() + '!' + key)) {
log.debug("{} Deleted session record ({})", getLogPrefix(), key);
+ final DDF output = new DDF();
+ ensureAgentRequestContext().setOutput(output);
} else {
log.debug("{} No session record ({})", getLogPrefix(), key);
+ ActionSupport.buildEvent(profileRequestContext, MISSING_SESSION);
}
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list