2 * Copyright 2001-2010 Internet2
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * SessionInitiator.cpp
20 * Pluggable runtime functionality that handles initiating sessions.
24 #include "exceptions.h"
25 #include "SPRequest.h"
26 #include "handler/SessionInitiator.h"
28 using namespace shibsp;
29 using namespace xmltooling;
33 # include <saml/saml2/metadata/Metadata.h>
34 using namespace opensaml::saml2md;
38 SHIBSP_DLLLOCAL PluginManager< SessionInitiator,string,pair<const DOMElement*,const char*> >::Factory ChainingSessionInitiatorFactory;
39 SHIBSP_DLLLOCAL PluginManager< SessionInitiator,string,pair<const DOMElement*,const char*> >::Factory Shib1SessionInitiatorFactory;
40 SHIBSP_DLLLOCAL PluginManager< SessionInitiator,string,pair<const DOMElement*,const char*> >::Factory SAML2SessionInitiatorFactory;
41 SHIBSP_DLLLOCAL PluginManager< SessionInitiator,string,pair<const DOMElement*,const char*> >::Factory WAYFSessionInitiatorFactory;
42 SHIBSP_DLLLOCAL PluginManager< SessionInitiator,string,pair<const DOMElement*,const char*> >::Factory SAMLDSSessionInitiatorFactory;
43 SHIBSP_DLLLOCAL PluginManager< SessionInitiator,string,pair<const DOMElement*,const char*> >::Factory TransformSessionInitiatorFactory;
44 SHIBSP_DLLLOCAL PluginManager< SessionInitiator,string,pair<const DOMElement*,const char*> >::Factory FormSessionInitiatorFactory;
45 SHIBSP_DLLLOCAL PluginManager< SessionInitiator,string,pair<const DOMElement*,const char*> >::Factory CookieSessionInitiatorFactory;
48 map<string,string> SessionInitiator::m_remapper;
50 void SHIBSP_API shibsp::registerSessionInitiators()
52 SPConfig& conf=SPConfig::getConfig();
53 conf.SessionInitiatorManager.registerFactory(CHAINING_SESSION_INITIATOR, ChainingSessionInitiatorFactory);
54 conf.SessionInitiatorManager.registerFactory(SHIB1_SESSION_INITIATOR, Shib1SessionInitiatorFactory);
55 conf.SessionInitiatorManager.registerFactory(SAML2_SESSION_INITIATOR, SAML2SessionInitiatorFactory);
56 conf.SessionInitiatorManager.registerFactory(WAYF_SESSION_INITIATOR, WAYFSessionInitiatorFactory);
57 conf.SessionInitiatorManager.registerFactory(SAMLDS_SESSION_INITIATOR, SAMLDSSessionInitiatorFactory);
58 conf.SessionInitiatorManager.registerFactory(TRANSFORM_SESSION_INITIATOR, TransformSessionInitiatorFactory);
59 conf.SessionInitiatorManager.registerFactory(FORM_SESSION_INITIATOR, FormSessionInitiatorFactory);
60 conf.SessionInitiatorManager.registerFactory(COOKIE_SESSION_INITIATOR, CookieSessionInitiatorFactory);
62 SessionInitiator::m_remapper["defaultACSIndex"] = "acsIndex";
65 SessionInitiator::SessionInitiator()
69 SessionInitiator::~SessionInitiator()
74 const char* SessionInitiator::getType() const
76 return "SessionInitiator";
79 void SessionInitiator::generateMetadata(SPSSODescriptor& role, const char* handlerURL) const
83 const char* loc = getString("Location").second;
84 string hurl(handlerURL);
88 auto_ptr_XMLCh widen(hurl.c_str());
90 RequestInitiator* ep = RequestInitiatorBuilder::buildRequestInitiator();
91 ep->setLocation(widen.get());
92 ep->setBinding(samlconstants::SP_REQUEST_INIT_NS);
93 Extensions* ext = role.getExtensions();
95 ext = ExtensionsBuilder::buildExtensions();
96 role.setExtensions(ext);
98 ext->getUnknownXMLObjects().push_back(ep);
102 const set<string>& SessionInitiator::getSupportedOptions() const
104 return m_supportedOptions;
107 bool SessionInitiator::checkCompatibility(SPRequest& request, bool isHandler) const
109 bool isPassive = false;
111 const char* flag = request.getParameter("isPassive");
113 isPassive = (*flag=='1' || *flag=='t');
116 pair<bool,bool> flagprop = getBool("isPassive");
117 isPassive = (flagprop.first && flagprop.second);
121 // It doesn't really make sense to use isPassive with automated sessions, but...
122 pair<bool,bool> flagprop = request.getRequestSettings().first->getBool("isPassive");
124 flagprop = getBool("isPassive");
125 isPassive = (flagprop.first && flagprop.second);
128 // Check for support of isPassive if it's used.
129 if (isPassive && getSupportedOptions().count("isPassive") == 0) {
131 log(SPRequest::SPInfo, "handler does not support isPassive option");
134 throw ConfigurationException("Unsupported option (isPassive) supplied to SessionInitiator.");
140 pair<bool,long> SessionInitiator::run(SPRequest& request, bool isHandler) const
142 const char* entityID = nullptr;
143 pair<bool,const char*> param = getString("entityIDParam");
145 entityID = request.getParameter(param.first ? param.second : "entityID");
146 if (!param.first && (!entityID || !*entityID))
147 entityID=request.getParameter("providerId");
149 if (!entityID || !*entityID) {
150 param = request.getRequestSettings().first->getString("entityID");
152 entityID = param.second;
154 if (!entityID || !*entityID)
155 entityID = getString("entityID").second;
157 string copy(entityID ? entityID : "");
160 return run(request, copy, isHandler);
162 catch (exception& ex) {
163 // If it's a handler operation, and isPassive is used or returnOnError is set, we trap the error.
165 bool returnOnError = false;
166 const char* flag = request.getParameter("isPassive");
167 if (flag && (*flag == 't' || *flag == '1')) {
168 returnOnError = true;
171 pair<bool,bool> flagprop = getBool("isPassive");
172 if (flagprop.first && flagprop.second) {
173 returnOnError = true;
176 flag = request.getParameter("returnOnError");
178 returnOnError = (*flag=='1' || *flag=='t');
181 flagprop = getBool("returnOnError");
182 returnOnError = (flagprop.first && flagprop.second);
188 // Log it and attempt to recover relay state so we can get back.
189 log(SPRequest::SPError, ex.what());
190 log(SPRequest::SPInfo, "trapping SessionInitiator error condition and returning to target location");
191 flag = request.getParameter("target");
192 string target(flag ? flag : "");
193 recoverRelayState(request.getApplication(), request, request, target, false);
194 return make_pair(true, request.sendRedirect(target.c_str()));