[cpp-sp] branch main updated: Flesh out admin logout with Hub operation.
Codeberg
noreply at shibboleth.net
Wed Oct 21 21:36:51 UTC 2026
This is an automated email from the git hooks/post-receive script.
codeberg pushed a commit to branch main
in repository cpp-sp.
View the commit online:
https://codeberg.org/Shibboleth/cpp-sp/commit/c3910880527e6c1c6516dd0d17e2eabedcc3592c
The following commit(s) were added to refs/heads/main by this push:
new c3910880 Flesh out admin logout with Hub operation.
c3910880 is described below
commit c3910880527e6c1c6516dd0d17e2eabedcc3592c
Author: Scott Cantor <scott at restingparrotsoftware.com>
AuthorDate: Wed Oct 21 17:36:16 2026 -0400
Flesh out admin logout with Hub operation.
---
configs/handlers.ini | 1 +
shibsp/handler/impl/AdminLogoutHandler.cpp | 100 ++++++++++++++++++++++++-----
shibsp/session/impl/CookieSessionCache.cpp | 3 +-
3 files changed, 88 insertions(+), 16 deletions(-)
diff --git a/configs/handlers.ini b/configs/handlers.ini
index 4890d6e3..16c355e5 100644
--- a/configs/handlers.ini
+++ b/configs/handlers.ini
@@ -27,6 +27,7 @@ type = AdminLogout
acl = 127.0.0.1 ::1
# true suppresses upstream signaling via Hub
#localOnly = true
+#revocationLifetime = 28800
# Legacy SSO/SLO endpoints for SP3 compatibility
diff --git a/shibsp/handler/impl/AdminLogoutHandler.cpp b/shibsp/handler/impl/AdminLogoutHandler.cpp
index 3d8425a7..5ff96b7c 100644
--- a/shibsp/handler/impl/AdminLogoutHandler.cpp
+++ b/shibsp/handler/impl/AdminLogoutHandler.cpp
@@ -24,6 +24,7 @@
#include "AgentConfig.h"
#include "handler/SecuredHandler.h"
#include "logging/Category.h"
+#include "remoting/RemotingService.h"
#include "session/SessionCache.h"
#include <sstream>
@@ -67,6 +68,9 @@ AdminLogoutHandler::AdminLogoutHandler(const ptree& pt) : AbstractHandler(pt), S
pair<bool,long> AdminLogoutHandler::run(SPRequest& request, bool isHandler) const
{
+ static const char REVOCATION_LIFETIME_PROP_NAME[] = "revocationLifetime";
+ static unsigned int REVOCATION_LIFETIME_PROP_DEFAULT = 3600 * 8;
+
// No front-channel notifications, so skip calling logout base class.
// Check ACL in base class.
@@ -83,30 +87,96 @@ pair<bool,long> AdminLogoutHandler::run(SPRequest& request, bool isHandler) cons
const char* applicationId = request.getRequestSettings().first->getString("applicationId", "default");
+ // Locate session. Note this may work *even* for client-backed sessions due to in-memory cache.
unique_lock<Session> session;
try {
- session = AgentConfig::getConfig().getAgent().getSessionCache()->find(applicationId, sessionId);
+ session = request.getAgent().getSessionCache()->find(applicationId, sessionId);
}
- catch (const std::exception& ex) {
+ catch (const exception& ex) {
request.error("error locating session: %s", ex.what());
- }
-
- // With no session, we return a 404 after "revoking" the session just to be safe.
- if (!session) {
- AgentConfig::getConfig().getAgent().getSessionCache()->remove(sessionId);
- istringstream msg("NOT FOUND");
- return make_pair(true, request.sendResponse(msg, HTTPResponse::SHIBSP_HTTP_STATUS_NOTFOUND));
+ istringstream msg("ERROR");
+ return make_pair(true, request.sendResponse(msg, HTTPResponse::SHIBSP_HTTP_STATUS_ERROR));
}
bool localOnly = getBool("localOnly", true);
+ // In a local only case, we attempt removal regardless.
if (localOnly) {
- session.unlock();
- AgentConfig::getConfig().getAgent().getSessionCache()->remove(sessionId);
-
- istringstream msg("OK");
- return make_pair(true, request.sendResponse(msg, HTTPResponse::SHIBSP_HTTP_STATUS_OK));
+ bool found(session);
+ if (session) {
+ session.unlock();
+ }
+ request.getAgent().getSessionCache()->remove(sessionId);
+ istringstream msg(found ? "OK" : "NOT FOUND");
+ return make_pair(true, request.sendResponse(msg,
+ found ? HTTPResponse::SHIBSP_HTTP_STATUS_OK : HTTPResponse::SHIBSP_HTTP_STATUS_NOTFOUND));
}
- return make_pair(false, 0L);
+ try {
+ // Before disposing of session, we need to copy out the opaque portion for the Hub.
+ DDF opaqueData;
+ if (session) {
+ opaqueData = session.mutex()->getOpaqueData().copy();
+ session.unlock();
+ }
+
+ // Dispose of the session locally.
+ request.getAgent().getSessionCache()->remove(sessionId);
+
+ // Revoke the session via the Hub.
+ DDF input = request.getAgent().getRemotingService()->build("logout-admin", request);
+ DDFJanitor inputJanitor(input);
+ input.addmember("session.id").string(sessionId);
+ input.getmember("session").add(opaqueData);
+ input.addmember("lifetime").longinteger(
+ getUnsignedInt(REVOCATION_LIFETIME_PROP_NAME, REVOCATION_LIFETIME_PROP_DEFAULT));
+
+ DDF output = request.getAgent().getRemotingService()->send(input);
+ DDFJanitor outputJanitor(output);
+
+ int status;
+ if (output["status"].isint()) {
+ status = output["status"].integer();
+ }
+ else {
+ request.error("absent status from Hub after revoking session (%s)", sessionId);
+ istringstream msg("ERROR");
+ return make_pair(true, request.sendResponse(msg, HTTPResponse::SHIBSP_HTTP_STATUS_ERROR));
+ }
+
+ switch (status) {
+ case 1:
+ {
+ request.info("Hub reported success revoking session (%s)", sessionId);
+ istringstream msg("OK");
+ return make_pair(true, request.sendResponse(msg, HTTPResponse::SHIBSP_HTTP_STATUS_OK));
+ }
+
+ case 0:
+ {
+ request.info("Hub reported partial success revoking session (%s)", sessionId);
+ istringstream msg("PARTIAL");
+ return make_pair(true, request.sendResponse(msg, HTTPResponse::SHIBSP_HTTP_STATUS_OK));
+ }
+
+ case -1:
+ {
+ request.error("Hub reported an error revoking session (%s)", sessionId);
+ istringstream msg("ERROR");
+ return make_pair(true, request.sendResponse(msg, HTTPResponse::SHIBSP_HTTP_STATUS_ERROR));
+ }
+
+ default:
+ {
+ request.error("unexpected status (%d) from Hub revoking session (%s)", status, sessionId);
+ istringstream msg("ERROR");
+ return make_pair(true, request.sendResponse(msg, HTTPResponse::SHIBSP_HTTP_STATUS_ERROR));
+ }
+ }
+ }
+ catch (const exception& e) {
+ request.error("error revoking session (%s) via Hub: %s", sessionId, e.what());
+ istringstream msg("ERROR");
+ return make_pair(true, request.sendResponse(msg, HTTPResponse::SHIBSP_HTTP_STATUS_ERROR));
+ }
}
diff --git a/shibsp/session/impl/CookieSessionCache.cpp b/shibsp/session/impl/CookieSessionCache.cpp
index 7a2a10ca..4d4f33b9 100644
--- a/shibsp/session/impl/CookieSessionCache.cpp
+++ b/shibsp/session/impl/CookieSessionCache.cpp
@@ -180,7 +180,8 @@ DDF CookieSessionCache::cache_read(
)
{
if (!request) {
- throw SessionException("Access to request object required to locate cookie-backed session.");
+ log(DEBUG_MARK, "no request available, no access to cookie-backed session store");
+ return DDF();
}
string encryptedSession = m_chunkedCookieManager->getChunkedCookieValue(*request);
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list