- shibsp::SecurityPolicy policy(application, &m_role, validate.first && validate.second);
-
- // Decode the message and process it in a protocol-specific way.
- auto_ptr<XMLObject> msg(m_decoder->decode(relayState, httpRequest, policy));
- if (!msg.get())
- throw BindingException("Failed to decode an SSO protocol response.");
- recoverRelayState(application, httpRequest, relayState);
- string key = implementProtocol(application, httpRequest, policy, settings, *msg.get());
-
- auto_ptr_char issuer(policy.getIssuer() ? policy.getIssuer()->getName() : NULL);
- if (issuer.get())
- entityID = issuer.get();
-
- return key;
+ auto_ptr<opensaml::SecurityPolicy> policy(
+ application.getServiceProvider().getSecurityPolicyProvider()->createSecurityPolicy(application, &m_role, policyId.second)
+ );
+
+ string relayState;
+ try {
+ // Decode the message and process it in a protocol-specific way.
+ auto_ptr<XMLObject> msg(m_decoder->decode(relayState, httpRequest, *(policy.get())));
+ if (!msg.get())
+ throw BindingException("Failed to decode an SSO protocol response.");
+ DDF postData = recoverPostData(application, httpRequest, httpResponse, relayState.c_str());
+ DDFJanitor postjan(postData);
+ recoverRelayState(application, httpRequest, httpResponse, relayState);
+ implementProtocol(application, httpRequest, httpResponse, *(policy.get()), NULL, *msg.get());
+
+ auto_ptr_char issuer(policy->getIssuer() ? policy->getIssuer()->getName() : nullptr);
+
+ // History cookie.
+ if (issuer.get() && *issuer.get())
+ maintainHistory(application, httpRequest, httpResponse, issuer.get());
+
+ // Now redirect to the state value. By now, it should be set to *something* usable.
+ // First check for POST data.
+ if (!postData.islist()) {
+ m_log.debug("ACS returning via redirect to: %s", relayState.c_str());
+ return make_pair(true, httpResponse.sendRedirect(relayState.c_str()));
+ }
+ else {
+ m_log.debug("ACS returning via POST to: %s", relayState.c_str());
+ return make_pair(true, sendPostResponse(application, httpResponse, relayState.c_str(), postData));
+ }
+ }
+ catch (XMLToolingException& ex) {
+ // Check for isPassive error condition.
+ const char* sc2 = ex.getProperty("statusCode2");
+ if (sc2 && !strcmp(sc2, "urn:oasis:names:tc:SAML:2.0:status:NoPassive")) {
+ pair<bool,bool> ignore = getBool("ignoreNoPassive", m_configNS.get()); // namespace-qualified if inside handler element
+ if (ignore.first && ignore.second && !relayState.empty()) {
+ m_log.debug("ignoring SAML status of NoPassive and redirecting to resource...");
+ return make_pair(true, httpResponse.sendRedirect(relayState.c_str()));
+ }
+ }
+ if (!relayState.empty())
+ ex.addProperty("RelayState", relayState.c_str());
+ throw;
+ }