void setParent(const PropertySet* parent);
void receive(DDF& in, ostream& out);
+ pair<bool,long> unwrap(SPRequest& request, DDF& out) const;
pair<bool,long> run(SPRequest& request, string& entityID, bool isHandler=true) const;
private:
pair<bool,long> doRequest(
const Application& application,
+ const HTTPRequest* httpRequest,
HTTPResponse& httpResponse,
const char* entityID,
const XMLCh* acsIndex,
bool forceAuthn,
const char* authnContextClassRef,
const char* authnContextComparison,
- string& relayState,
- string& postData
+ string& relayState
) const;
string m_appId;
target = option;
// Always need to recover target URL to compute handler below.
- // don't think we need to recover post data here though
recoverRelayState(request.getApplication(), request, request, target, false);
pair<bool,bool> flag;
// We're running as a "virtual handler" from within the filter.
// The target resource is the current one and everything else is defaulted.
target=request.getRequestURL();
- postData = getPostData(request);
const PropertySet* settings = request.getRequestSettings().first;
pair<bool,bool> flag = settings->getBool("isPassive");
}
return doRequest(
- app, request, entityID.c_str(),
+ app, &request, request, entityID.c_str(),
ix.second,
ACS ? XMLString::equals(ACS->getString("Binding").second, samlconstants::SAML20_BINDING_HTTP_ARTIFACT) : false,
NULL, NULL,
isPassive, forceAuthn,
acClass.first ? acClass.second : NULL,
acComp.first ? acComp.second : NULL,
- target,
- postData
+ target
);
}
}
return doRequest(
- app, request, entityID.c_str(),
+ app, &request, request, entityID.c_str(),
NULL,
ACS ? XMLString::equals(ACS->getString("Binding").second, samlconstants::SAML20_BINDING_HTTP_ARTIFACT) : false,
ACSloc.c_str(), ACS ? ACS->getXMLString("Binding").second : NULL,
isPassive, forceAuthn,
acClass.first ? acClass.second : NULL,
acComp.first ? acComp.second : NULL,
- target,
- postData
+ target
);
}
if (!target.empty())
in.addmember("RelayState").string(target.c_str());
- if (!postData.empty()) {
- in.addmember("PostData").string(postData.c_str());
- m_log.debug("saml2SI remoting %d posted bytes", postData.length());
- }
-
// Remote the processing.
out = request.getServiceProvider().getListenerService()->send(in);
return unwrap(request, out);
}
+pair<bool,long> SAML2SessionInitiator::unwrap(SPRequest& request, DDF& out) const
+{
+ // See if there's any response to send back.
+ if (!out["redirect"].isnull() || !out["response"].isnull()) {
+ // If so, we're responsible for handling the POST data, probably by dropping a cookie.
+ preservePostData(request.getApplication(), request, request, out["RelayState"].string());
+ }
+ return RemotedHandler::unwrap(request, out);
+}
+
void SAML2SessionInitiator::receive(DDF& in, ostream& out)
{
// Find application.
// a false/0 return, which we just return as an empty structure, or a response/redirect,
// which we capture in the facade and send back.
doRequest(
- *app, *http.get(), in["entity_id"].string(),
+ *app, NULL, *http.get(), in["entity_id"].string(),
index.get(),
(in["artifact"].integer() != 0),
in["acsLocation"].string(), bind.get(),
in["isPassive"].integer()==1, in["forceAuthn"].integer()==1,
in["authnContextClassRef"].string(), in["authnContextComparison"].string(),
- relayState,
- postData
+ relayState
);
+ if (!ret.isstruct())
+ ret.structure();
+ ret.addmember("RelayState").string(relayState.c_str());
out << ret;
}
pair<bool,long> SAML2SessionInitiator::doRequest(
const Application& app,
+ const HTTPRequest* httpRequest,
HTTPResponse& httpResponse,
const char* entityID,
const XMLCh* acsIndex,
bool forceAuthn,
const char* authnContextClassRef,
const char* authnContextComparison,
- string& relayState,
- string& postData
+ string& relayState
) const
{
#ifndef SHIBSP_LITE
}
preserveRelayState(app, httpResponse, relayState);
- preservePostData(app, httpResponse, postData, relayState);
auto_ptr<AuthnRequest> req(m_requestTemplate ? m_requestTemplate->cloneAuthnRequest() : AuthnRequestBuilder::buildAuthnRequest());
if (m_requestTemplate) {
auto_ptr_char dest(ep ? ep->getLocation() : NULL);
+ if (httpRequest) {
+ // If the request object is available, we're responsible for the POST data.
+ preservePostData(app, *httpRequest, httpResponse, relayState.c_str());
+ }
+
long ret = sendMessage(
*encoder, req.get(), relayState.c_str(), dest.get(), role, app, httpResponse, role ? role->WantAuthnRequestsSigned() : false
);