[cpp-sp] branch main updated: Adjustments to response URL handling.
Scott Cantor
cantor.2 at osu.edu
Mon Feb 10 21:38:51 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=dba93a4d806f9c033cc6658d7a8414ed79c5423a
The following commit(s) were added to refs/heads/main by this push:
new dba93a4d Adjustments to response URL handling.
dba93a4d is described below
commit dba93a4d806f9c033cc6658d7a8414ed79c5423a
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Mon Feb 10 16:38:47 2025 -0500
Adjustments to response URL handling.
---
configs/handlers.ini | 8 ++-
shibsp/Makefile.am | 5 +-
shibsp/handler/HandlerConfiguration.h | 11 +++-
shibsp/handler/impl/AbstractHandler.cpp | 8 ++-
.../handler/impl/DefaultHandlerConfiguration.cpp | 39 ++++++++++---
shibsp/handler/impl/SessionInitiator.cpp | 20 ++++---
shibsp/handler/impl/TokenConsumer.cpp | 64 ++++++++++++++++++++++
shibsp/remoting/ddf.h | 3 +-
8 files changed, 132 insertions(+), 26 deletions(-)
diff --git a/configs/handlers.ini b/configs/handlers.ini
index 606fc329..3a972f4e 100644
--- a/configs/handlers.ini
+++ b/configs/handlers.ini
@@ -1,4 +1,10 @@
-[/Status]
+[Status]
type = Status
acl = 127.0.0.1 ::1
+[Login]
+type = SessionInitiator
+
+[Validate]
+type = TokenConsumer
+
diff --git a/shibsp/Makefile.am b/shibsp/Makefile.am
index 6e2327c8..b868e719 100644
--- a/shibsp/Makefile.am
+++ b/shibsp/Makefile.am
@@ -48,8 +48,7 @@ handinclude_HEADERS = \
handler/LogoutHandler.h \
handler/LogoutInitiator.h \
handler/RemotedHandler.h \
- handler/SecuredHandler.h \
- handler/SessionInitiator.h
+ handler/SecuredHandler.h
ioinclude_HEADERS = \
io/GenericRequest.h \
@@ -105,7 +104,6 @@ libshibsp_la_SOURCES = \
attribute/ScopedAttribute.cpp \
handler/impl/AbstractHandler.cpp \
handler/impl/AdminLogoutInitiator.cpp \
- handler/impl/AssertionConsumerService.cpp \
handler/impl/AttributeCheckerHandler.cpp \
handler/impl/LocalLogoutInitiator.cpp \
handler/impl/DefaultHandlerConfiguration.cpp \
@@ -117,6 +115,7 @@ libshibsp_la_SOURCES = \
handler/impl/SessionHandler.cpp \
handler/impl/SessionInitiator.cpp \
handler/impl/StatusHandler.cpp \
+ handler/impl/TokenConsumer.cpp \
impl/AgentConfig.cpp \
impl/DefaultAgent.cpp \
impl/ChainingAccessControl.cpp \
diff --git a/shibsp/handler/HandlerConfiguration.h b/shibsp/handler/HandlerConfiguration.h
index 3f475757..f6bc32a4 100644
--- a/shibsp/handler/HandlerConfiguration.h
+++ b/shibsp/handler/HandlerConfiguration.h
@@ -63,7 +63,9 @@ namespace shibsp {
virtual const Handler& getSessionInitiator() const=0;
/**
- * Gets a DDF object suitable for copying into session initiator requests to the hub.
+ * Gets a DDF object suitable for adding into session initiator requests to the hub.
+ *
+ * <p>This is a newly allocated list that must be freed by the caller.</p>
*
* <p>This is required to support the communication of the possible response
* paths for the agent to the hub when formulating SSO protocol requests, and encapsulates
@@ -76,9 +78,12 @@ namespace shibsp {
* "meta-informatin" required to support this legacy practice will be embedded within
* the structure returned.</p>
*
- * @return DDF object encapsulating token consumer handler metadata
+ * @param handlerURL the handler base URL with which to prefix the token consumer
+ * endpoint paths
+ *
+ * @return new DDF object encapsulating token consumer handler metadata
*/
- virtual const DDF& getTokenConsumerInfo() const=0;
+ virtual DDF getTokenConsumerInfo(const char* handlerURL=nullptr) const=0;
/**
* Create a new HandlerConfiguration based on the supplied configuration file.
diff --git a/shibsp/handler/impl/AbstractHandler.cpp b/shibsp/handler/impl/AbstractHandler.cpp
index 75b79ee2..1c8850e5 100644
--- a/shibsp/handler/impl/AbstractHandler.cpp
+++ b/shibsp/handler/impl/AbstractHandler.cpp
@@ -52,7 +52,6 @@ namespace shibsp {
//extern SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<ptree&,const char*> >::Factory SAML2LogoutFactory;
//extern SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<ptree&,const char*> >::Factory AttributeCheckerFactory;
//extern SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<ptree&,const char*> >::Factory MetadataGeneratorFactory;
- extern SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<ptree&,const char*> >::Factory StatusHandlerFactory;
//extern SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<ptree&,const char*> >::Factory SessionHandlerFactory;
//extern SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<ptree&,const char*> >::Factory AdminLogoutInitiatorFactory;
@@ -60,6 +59,9 @@ namespace shibsp {
//extern SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<ptree&,const char*> >::Factory LocalLogoutInitiatorFactory;
extern SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<ptree&,const char*> >::Factory SessionInitiatorFactory;
+ extern SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<ptree&,const char*> >::Factory StatusHandlerFactory;
+ extern SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<ptree&,const char*> >::Factory TokenConsumerFactory;
+
void SHIBSP_DLLLOCAL generateRandomHex(std::string& buf, unsigned int len) {
static char DIGITS[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
@@ -88,8 +90,6 @@ void SHIBSP_API shibsp::registerHandlers()
//conf.HandlerManager.registerFactory(SAML20_ASSERTION_CONSUMER_SERVICE, SAML2ConsumerFactory);
- conf.HandlerManager.registerFactory(STATUS_HANDLER, StatusHandlerFactory);
-
//conf.HandlerManager.registerFactory(SAML20_LOGOUT_HANDLER, SAML2LogoutFactory);
//conf.HandlerManager.registerFactory(ADMIN_LOGOUT_INITIATOR, AdminLogoutInitiatorFactory);
@@ -97,6 +97,8 @@ void SHIBSP_API shibsp::registerHandlers()
//conf.HandlerManager.registerFactory(LOCAL_LOGOUT_INITIATOR, LocalLogoutInitiatorFactory);
conf.HandlerManager.registerFactory(SESSION_INITIATOR_HANDLER, SessionInitiatorFactory);
+ conf.HandlerManager.registerFactory(STATUS_HANDLER, StatusHandlerFactory);
+ conf.HandlerManager.registerFactory(TOKEN_CONSUMER_HANDLER, TokenConsumerFactory);
}
Handler::Handler()
diff --git a/shibsp/handler/impl/DefaultHandlerConfiguration.cpp b/shibsp/handler/impl/DefaultHandlerConfiguration.cpp
index c0a7b524..233db510 100644
--- a/shibsp/handler/impl/DefaultHandlerConfiguration.cpp
+++ b/shibsp/handler/impl/DefaultHandlerConfiguration.cpp
@@ -48,7 +48,7 @@ namespace {
const Handler* getHandler(const char* path) const;
const Handler& getSessionInitiator() const;
- const DDF& getTokenConsumerInfo() const;
+ DDF getTokenConsumerInfo(const char* handlerURL=nullptr) const;
private:
ptree m_pt;
@@ -83,14 +83,19 @@ DefaultHandlerConfiguration::DefaultHandlerConfiguration(const char* pathname)
throw ConfigurationException("Multiple SessionInitiator handlers were configured, only one is permitted.");
}
+ string handlerPath(child.first);
+ if (handlerPath.front() != '/') {
+ handlerPath = '/' + handlerPath;
+ }
+
// Handlers have to know their own path in some cases, so that has to be injected into the
// factory method, as ptrees don't know their own name unfortunately, thus the section header
// value is lost when passing the section tree itself in.
unique_ptr<Handler> handler(AgentConfig::getConfig().HandlerManager.newPlugin(
- type.get(), pair<ptree&,const char*>(child.second, child.first.c_str()), false));
+ type.get(), pair<ptree&,const char*>(child.second, handlerPath.c_str()), false));
- m_handlerMap[child.first] = std::move(handler);
- log.info("config (%s) installed %s handler at %s", pathname, type.get().c_str(), child.first.c_str());
+ m_handlerMap[handlerPath] = std::move(handler);
+ log.info("config (%s) installed %s handler at %s", pathname, type.get().c_str(), handlerPath.c_str());
// Save off a single SessionInitiator.
if (*type == SESSION_INITIATOR_HANDLER) {
@@ -98,7 +103,7 @@ DefaultHandlerConfiguration::DefaultHandlerConfiguration(const char* pathname)
} else if (*type == TOKEN_CONSUMER_HANDLER) {
DDF tokenConsumer(nullptr);
// String value of DDF is the handler location.
- tokenConsumer.string(child.first.c_str());
+ tokenConsumer.string(handlerPath.c_str());
m_tokenConsumerConfig.add(tokenConsumer);
// Check for legacy "binding" value to carry along with path as the name of the node.
@@ -108,6 +113,14 @@ DefaultHandlerConfiguration::DefaultHandlerConfiguration(const char* pathname)
}
}
}
+
+ // If a single token consumer with no binding label is installed, convert list to unnamed string.
+ if (m_tokenConsumerConfig.integer() == 1 && !m_tokenConsumerConfig.first().name()) {
+ DDF singleEndpoint)nullptr);
+ singleEndpoint.string(m_tokenConsumerConfig.first().string());
+ m_tokenConsumerConfig.destroy();
+ m_tokenConsumerConfig = singleEndpoint;
+ }
}
const Handler* DefaultHandlerConfiguration::getHandler(const char* path) const
@@ -129,9 +142,21 @@ const Handler& DefaultHandlerConfiguration::getSessionInitiator() const
throw runtime_error("No SessionInitiator configured?");
}
-const DDF& DefaultHandlerConfiguration::getTokenConsumerInfo() const
+DDF DefaultHandlerConfiguration::getTokenConsumerInfo(const char* handlerURL) const
{
- return m_tokenConsumerConfig;
+ DDF dup = m_tokenConsumerConfig.copy();
+
+ if (handlerURL) {
+ DDF endpoint = dup.first();
+ while (!endpoint.isnull()) {
+ string path(handlerURL);
+ path += endpoint.string();
+ endpoint.string(path.c_str());
+ endpoint = dup.next();
+ }
+ }
+
+ return dup;
}
unique_ptr<HandlerConfiguration> HandlerConfiguration::newHandlerConfiguration(const char* pathname)
diff --git a/shibsp/handler/impl/SessionInitiator.cpp b/shibsp/handler/impl/SessionInitiator.cpp
index cbd4f72f..2be3b6f5 100644
--- a/shibsp/handler/impl/SessionInitiator.cpp
+++ b/shibsp/handler/impl/SessionInitiator.cpp
@@ -91,6 +91,7 @@ pair<bool,long> SessionInitiator::run(SPRequest& request, bool isHandler) const
{
try {
string state, target, handler;
+ const char* handlerBaseURL = nullptr;
if (isHandler) {
// Check for a state parameter in the query string.
@@ -100,13 +101,15 @@ pair<bool,long> SessionInitiator::run(SPRequest& request, bool isHandler) const
state = param;
// handler can be derived from "this" URL since this is a re-entrant call to this handler,
// i.e., we know this is the right URL to use because "it already was" originally.
- handler = request.getHandlerURL(request.getRequestURL()) + m_path;
+ handlerBaseURL = request.getHandlerURL(request.getRequestURL());
+ handler = handlerBaseURL + m_path;
}
else {
// target will come from query string, map, or handler or fall back to this request.
target = getString("target", request, request.getRequestURL());
// handler is derived from the target resource.
- handler = request.getHandlerURL(target.c_str()) + m_path;
+ handlerBaseURL = request.getHandlerURL(target.c_str());
+ handler = handlerBaseURL + m_path;
}
}
else {
@@ -115,7 +118,8 @@ pair<bool,long> SessionInitiator::run(SPRequest& request, bool isHandler) const
HANDLER_PROPERTY_FIXED | HANDLER_PROPERTY_MAP);
// state is empty since this is a direct resource request.
// handler is derived from the target resource
- handler = request.getHandlerURL(target.c_str()) + m_path;
+ handlerBaseURL = request.getHandlerURL(target.c_str());
+ handler = handlerBaseURL + m_path;
}
const PropertySet* settings = request.getRequestSettings().first;
@@ -133,14 +137,14 @@ pair<bool,long> SessionInitiator::run(SPRequest& request, bool isHandler) const
input.addmember("state").string(state.c_str());
}
- const DDF& consumers = request.getAgent().getHandlerConfiguration(
- settings->getString("handlerConfigID")).getTokenConsumerInfo();
- DDF dup = consumers.copy();
+ // Add copy of token consumer structure.
+ DDF dup = request.getAgent().getHandlerConfiguration(
+ settings->getString("handlerConfigID")).getTokenConsumerInfo(handlerBaseURL);
input.add(dup);
DDF wrapped = wrapRequest(request, m_remotedHeaders,
- !isHandler && getBool("preservePostData", request, false,
- HANDLER_PROPERTY_FIXED | HANDLER_PROPERTY_MAP));
+ !isHandler &&
+ getBool("preservePostData", request, false, HANDLER_PROPERTY_FIXED | HANDLER_PROPERTY_MAP));
input.add(wrapped);
for (const string& propname : m_requestMapperSettings) {
diff --git a/shibsp/handler/impl/TokenConsumer.cpp b/shibsp/handler/impl/TokenConsumer.cpp
new file mode 100644
index 00000000..34f5d9f1
--- /dev/null
+++ b/shibsp/handler/impl/TokenConsumer.cpp
@@ -0,0 +1,64 @@
+/**
+ * Licensed 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.
+ */
+
+/**
+ * handler/impl/TokenCOnsumer.cpp
+ *
+ * SSO protocol response handler.
+ */
+
+#include "internal.h"
+#include "exceptions.h"
+#include "SPRequest.h"
+#include "handler/AbstractHandler.h"
+#include "logging/Category.h"
+
+#include <ctime>
+#include <boost/property_tree/ptree.hpp>
+
+using namespace shibsp;
+using namespace boost::property_tree;
+using namespace std;
+
+namespace {
+ class SHIBSP_DLLLOCAL TokenConsumer : public virtual AbstractHandler {
+ public:
+ TokenConsumer(const ptree& pt, const char* path);
+ virtual ~TokenConsumer() {}
+
+ pair<bool,long> run(SPRequest& request, bool isHandler) const;
+
+ private:
+ string m_path;
+ vector<string> m_remotedHeaders;
+ };
+};
+
+namespace shibsp {
+ Handler* SHIBSP_DLLLOCAL TokenConsumerFactory(const pair<ptree&,const char*>& p, bool) {
+ return new TokenConsumer(p.first, p.second);
+ }
+};
+
+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);
+}
diff --git a/shibsp/remoting/ddf.h b/shibsp/remoting/ddf.h
index 7bc1e914..ed1f25c8 100644
--- a/shibsp/remoting/ddf.h
+++ b/shibsp/remoting/ddf.h
@@ -55,7 +55,8 @@ namespace shibsp {
DDF copy() const; // deep copy routine
// property accessors
- const char* name() const; DDF& name(const char* n);
+ const char* name() const;
+ DDF& name(const char* n);
// basic type checking
bool isnull() const;
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list