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 SHIBSP_DLLLOCAL PluginManager< SessionInitiator,string,pair<const DOMElement*,const char*> >::Factory ChainingSessionInitiatorFactory;
34 SHIBSP_DLLLOCAL PluginManager< SessionInitiator,string,pair<const DOMElement*,const char*> >::Factory Shib1SessionInitiatorFactory;
35 SHIBSP_DLLLOCAL PluginManager< SessionInitiator,string,pair<const DOMElement*,const char*> >::Factory SAML2SessionInitiatorFactory;
36 SHIBSP_DLLLOCAL PluginManager< SessionInitiator,string,pair<const DOMElement*,const char*> >::Factory WAYFSessionInitiatorFactory;
37 SHIBSP_DLLLOCAL PluginManager< SessionInitiator,string,pair<const DOMElement*,const char*> >::Factory SAMLDSSessionInitiatorFactory;
38 SHIBSP_DLLLOCAL PluginManager< SessionInitiator,string,pair<const DOMElement*,const char*> >::Factory TransformSessionInitiatorFactory;
39 SHIBSP_DLLLOCAL PluginManager< SessionInitiator,string,pair<const DOMElement*,const char*> >::Factory FormSessionInitiatorFactory;
40 SHIBSP_DLLLOCAL PluginManager< SessionInitiator,string,pair<const DOMElement*,const char*> >::Factory CookieSessionInitiatorFactory;
43 map<string,string> SessionInitiator::m_remapper;
45 void SHIBSP_API shibsp::registerSessionInitiators()
47 SPConfig& conf=SPConfig::getConfig();
48 conf.SessionInitiatorManager.registerFactory(CHAINING_SESSION_INITIATOR, ChainingSessionInitiatorFactory);
49 conf.SessionInitiatorManager.registerFactory(SHIB1_SESSION_INITIATOR, Shib1SessionInitiatorFactory);
50 conf.SessionInitiatorManager.registerFactory(SAML2_SESSION_INITIATOR, SAML2SessionInitiatorFactory);
51 conf.SessionInitiatorManager.registerFactory(WAYF_SESSION_INITIATOR, WAYFSessionInitiatorFactory);
52 conf.SessionInitiatorManager.registerFactory(SAMLDS_SESSION_INITIATOR, SAMLDSSessionInitiatorFactory);
53 conf.SessionInitiatorManager.registerFactory(TRANSFORM_SESSION_INITIATOR, TransformSessionInitiatorFactory);
54 conf.SessionInitiatorManager.registerFactory(FORM_SESSION_INITIATOR, FormSessionInitiatorFactory);
55 conf.SessionInitiatorManager.registerFactory(COOKIE_SESSION_INITIATOR, CookieSessionInitiatorFactory);
57 SessionInitiator::m_remapper["defaultACSIndex"] = "acsIndex";
60 SessionInitiator::SessionInitiator()
64 SessionInitiator::~SessionInitiator()
69 const char* SessionInitiator::getType() const
71 return "SessionInitiator";
75 const set<string>& SessionInitiator::getSupportedOptions() const
77 return m_supportedOptions;
80 bool SessionInitiator::checkCompatibility(SPRequest& request, bool isHandler) const
82 bool isPassive = false;
84 const char* flag = request.getParameter("isPassive");
86 isPassive = (*flag=='1' || *flag=='t');
89 pair<bool,bool> flagprop = getBool("isPassive");
90 isPassive = (flagprop.first && flagprop.second);
94 // It doesn't really make sense to use isPassive with automated sessions, but...
95 pair<bool,bool> flagprop = request.getRequestSettings().first->getBool("isPassive");
97 flagprop = getBool("isPassive");
98 isPassive = (flagprop.first && flagprop.second);
101 // Check for support of isPassive if it's used.
102 if (isPassive && getSupportedOptions().count("isPassive") == 0) {
104 log(SPRequest::SPInfo, "handler does not support isPassive option");
107 throw ConfigurationException("Unsupported option (isPassive) supplied to SessionInitiator.");
113 pair<bool,long> SessionInitiator::run(SPRequest& request, bool isHandler) const
115 const char* entityID = NULL;
116 pair<bool,const char*> param = getString("entityIDParam");
118 entityID = request.getParameter(param.first ? param.second : "entityID");
119 if (!param.first && (!entityID || !*entityID))
120 entityID=request.getParameter("providerId");
122 if (!entityID || !*entityID) {
123 param = request.getRequestSettings().first->getString("entityID");
125 entityID = param.second;
127 if (!entityID || !*entityID)
128 entityID = getString("entityID").second;
130 string copy(entityID ? entityID : "");
133 return run(request, copy, isHandler);
135 catch (exception& ex) {
136 // If it's a handler operation, and isPassive is used or returnOnError is set, we trap the error.
138 bool returnOnError = false;
139 const char* flag = request.getParameter("isPassive");
140 if (flag && (*flag == 't' || *flag == '1')) {
141 returnOnError = true;
144 pair<bool,bool> flagprop = getBool("isPassive");
145 if (flagprop.first && flagprop.second) {
146 returnOnError = true;
149 flag = request.getParameter("returnOnError");
151 returnOnError = (*flag=='1' || *flag=='t');
154 flagprop = getBool("returnOnError");
155 returnOnError = (flagprop.first && flagprop.second);
161 // Log it and attempt to recover relay state so we can get back.
162 log(SPRequest::SPError, ex.what());
163 log(SPRequest::SPInfo, "trapping SessionInitiator error condition and returning to target location");
164 const char* flag = request.getParameter("target");
165 string target(flag ? flag : "");
166 recoverRelayState(request.getApplication(), request, request, target, false);
167 return make_pair(true, request.sendRedirect(target.c_str()));