[cpp-sp] branch main updated: Flesh out TokenConsumer handler.

Scott Cantor cantor.2 at osu.edu
Thu Apr 3 19:48:11 UTC 2025


This is an automated email from the git hooks/post-receive script.

scantor pushed a commit to branch main
in repository cpp-sp.

View the commit online:
http://git.shibboleth.net/view/?p=cpp-sp.git;a=commit;h=5591cdf68af5a9aa11147a333a0d557c45f69d1b

The following commit(s) were added to refs/heads/main by this push:
     new 5591cdf6 Flesh out TokenConsumer handler.
5591cdf6 is described below

commit 5591cdf68af5a9aa11147a333a0d557c45f69d1b
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Thu Apr 3 15:48:03 2025 -0400

    Flesh out TokenConsumer handler.
---
 shibsp/exceptions.cpp                            |  4 +-
 shibsp/exceptions.h                              |  4 +-
 shibsp/handler/impl/SessionInitiator.cpp         |  2 +-
 shibsp/handler/impl/TokenConsumer.cpp            | 86 +++++++++++++++++++++++-
 shibsp/remoting/impl/AbstractRemotingService.cpp |  5 ++
 5 files changed, 95 insertions(+), 6 deletions(-)

diff --git a/shibsp/exceptions.cpp b/shibsp/exceptions.cpp
index 80cd0510..fc162b6d 100644
--- a/shibsp/exceptions.cpp
+++ b/shibsp/exceptions.cpp
@@ -97,7 +97,7 @@ string AgentException::toQueryString() const
     return q;
 }
 
-void AgentException::log(const SPRequest& request) const
+void AgentException::log(const SPRequest& request, Priority::Value priority) const
 {
     ostringstream msg;
     msg << what() << ": [";
@@ -111,5 +111,5 @@ void AgentException::log(const SPRequest& request) const
 
     msg << ']';
 
-    request.log(Priority::SHIB_ERROR, msg.str());
+    request.log(priority, msg.str());
 }
diff --git a/shibsp/exceptions.h b/shibsp/exceptions.h
index 809bcbc8..6c6276c8 100644
--- a/shibsp/exceptions.h
+++ b/shibsp/exceptions.h
@@ -22,6 +22,7 @@
 #define __shibsp_exceptions_h__
 
 #include <shibsp/base.h>
+#include <shibsp/logging/Priority.h>
 
 #include <exception>
 #include <string>
@@ -137,8 +138,9 @@ namespace shibsp {
          * Log an error through this request using the exception properties as input.
          * 
          * @param request SP request
+         * @param priority logging level
          */
-        void log(const SPRequest& request) const;        
+        void log(const SPRequest& request, Priority::Value priority=Priority::SHIB_ERROR) const;
 
     private:
         int m_status;
diff --git a/shibsp/handler/impl/SessionInitiator.cpp b/shibsp/handler/impl/SessionInitiator.cpp
index 7d511869..313d6ce0 100644
--- a/shibsp/handler/impl/SessionInitiator.cpp
+++ b/shibsp/handler/impl/SessionInitiator.cpp
@@ -186,7 +186,7 @@ pair<bool,long> SessionInitiator::run(SPRequest& request, bool isHandler) const
             if (returnOnError) {
                 m_log.warn(ex.what());
                 const char* error_target = agent_ex ? agent_ex->getProperty("target") : nullptr;
-                // Make sure the target isn't the same as this handler, so avoid a loop.
+                // Make sure the target isn't the same as this handler, to avoid a loop.
                 if (error_target && strcmp(error_target, handler.c_str())) {
                     m_log.info("trapping SessionInitiator failure and returning to target location");
                     request.limitRedirect(error_target);
diff --git a/shibsp/handler/impl/TokenConsumer.cpp b/shibsp/handler/impl/TokenConsumer.cpp
index 34f5d9f1..972c1b23 100644
--- a/shibsp/handler/impl/TokenConsumer.cpp
+++ b/shibsp/handler/impl/TokenConsumer.cpp
@@ -20,11 +20,16 @@
 
 #include "internal.h"
 #include "exceptions.h"
+#include "Agent.h"
+#include "AgentConfig.h"
 #include "SPRequest.h"
 #include "handler/AbstractHandler.h"
 #include "logging/Category.h"
+#include "remoting/RemotingService.h"
+#include "util/URLEncoder.h"
 
 #include <ctime>
+#include <sstream>
 #include <boost/property_tree/ptree.hpp>
 
 using namespace shibsp;
@@ -55,10 +60,87 @@ TokenConsumer::TokenConsumer(const ptree& pt, const char* path)
     : AbstractHandler(pt, Category::getInstance(SHIBSP_LOGCAT ".Handler.TokenConsumer")),
         m_path(path), m_remotedHeaders({ "Cookie" })
 {
-
 }
 
 pair<bool,long> TokenConsumer::run(SPRequest& request, bool isHandler) const
 {
-    return make_pair(false, 0);
+    try {
+        DDF input("token-consumer");
+        DDFJanitor inputJanitor(input);    
+        input.structure();
+        input.addmember("application").string(
+            request.getRequestSettings().first->getString("applicationId", "default"));
+
+        DDF wrapped = wrapRequest(request, m_remotedHeaders);
+        input.add(wrapped);
+
+        DDF output = request.getAgent().getRemotingService()->send(input);
+        DDFJanitor outputJanitor(output);
+
+        // TODO: process outbound session data
+
+        const char* sessionHook = request.getRequestSettings().first->getString("sessionHook");
+        if (sessionHook) {
+            string hook(sessionHook);
+            request.absolutize(hook);
+
+            // Compute the return URL. We use a self-referential link plus a hook indicator to break the cycle.
+            // The target also must be included.
+            const URLEncoder& encoder = AgentConfig::getConfig().getURLEncoder();
+            string returnURL = request.getRequestURL();
+            returnURL = returnURL.substr(0, returnURL.find('?')) + "?hook=1";
+
+            const char* target = output.getmember("http.redirect").string();
+            string encodedTarget;
+            if (target) {
+                encodedTarget = encoder.encode(target);
+                returnURL += "&target=" + encodedTarget;
+            }
+            if (hook.find('?') == string::npos) {
+                hook += '?';
+            }
+            else {
+                hook += '&';
+            }
+            hook += "return=" + encoder.encode(returnURL.c_str());
+
+            // Add the translated target resource explicitly in case it's of interest.
+            if (!encodedTarget.empty()) {
+                hook += "&target=" + encodedTarget;
+            }
+
+            // Overrwrite the original redirection target and issue.
+            // This is necessary to ensure any Set-Cookie headers placed by the hub will reach the client.
+            output.addmember("http.redirect").unsafe_string(hook.c_str());
+            return unwrapResponse(request, output);
+        }
+
+        // TODO: remove POC debugging code...
+        stringstream dump;
+        dump << output;
+        return make_pair(true,request.sendResponse(dump));
+        
+        //return unwrapResponse(request, output);
+    }
+    catch (exception& ex) {
+        AgentException* agent_ex = dynamic_cast<AgentException*>(&ex);
+        if (agent_ex) {
+            agent_ex->addProperty("handlerType", TOKEN_CONSUMER_HANDLER);
+        }
+        
+        const char* passive = agent_ex ? agent_ex->getProperty("passive") : nullptr;
+        if (passive && !strcmp(passive, "1")) {
+            agent_ex->log(request, Priority::SHIB_WARN);
+            const char* error_target = agent_ex->getProperty("target");
+
+            // TODO: either recover POST data or clean up recovery state?
+
+            // Make sure the target isn't the same as this handler, so avoid a loop.
+            request.log(Priority::SHIB_INFO,
+                "trapping TokenConsumer failure and returning to target location for passive request");
+            request.limitRedirect(error_target);
+            return make_pair(true, request.sendRedirect(error_target));
+        }
+        throw;
+    }
 }
diff --git a/shibsp/remoting/impl/AbstractRemotingService.cpp b/shibsp/remoting/impl/AbstractRemotingService.cpp
index faf8aaa7..a5d2b11b 100644
--- a/shibsp/remoting/impl/AbstractRemotingService.cpp
+++ b/shibsp/remoting/impl/AbstractRemotingService.cpp
@@ -55,6 +55,11 @@ DDF AbstractRemotingService::send(const DDF& in) const
         if (target) {
             ex.addProperty("target", target);
         }
+
+        if (output.getmember("passive").integer() == 1) {
+            ex.addProperty("passive", "1");
+        }
+
         output.destroy();
         throw ex;
     }

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list