# include "lite/SAMLConstants.h"
#endif
-#include <boost/scoped_ptr.hpp>
-
using namespace shibsp;
using namespace xmltooling;
using namespace boost;
) const;
string m_appId;
+ auto_ptr_char m_protocol;
#ifndef SHIBSP_LITE
auto_ptr<LogoutRequest> buildRequest(
const Application& application, const Session& session, const RoleDescriptor& role, const MessageEncoder* encoder=nullptr
return e;
}
+ bool m_async;
vector<string> m_bindings;
map< string,boost::shared_ptr<MessageEncoder> > m_encoders;
#endif
- auto_ptr_char m_protocol;
};
#if defined (_MSC_VER)
SAML2LogoutInitiator::SAML2LogoutInitiator(const DOMElement* e, const char* appId)
: AbstractHandler(e, Category::getInstance(SHIBSP_LOGCAT".LogoutInitiator.SAML2")), m_appId(appId), m_protocol(samlconstants::SAML20P_NS)
+#ifndef SHIBSP_LITE
+ ,m_async(true)
+#endif
{
// If Location isn't set, defer initialization until the setParent call.
pair<bool,const char*> loc = getString("Location");
#ifndef SHIBSP_LITE
if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
+ pair<bool,bool> async = getBool("asynchronous");
+ m_async = !async.first || async.second;
+
string dupBindings;
pair<bool,const char*> outgoing = getString("outgoingBindings");
if (outgoing.first) {
dupBindings = outgoing.second;
+ trim(dupBindings);
}
else {
// No override, so we'll install a default binding precedence.
logout_event->m_logoutType = LogoutEvent::LOGOUT_EVENT_UNKNOWN;
logout_event->m_saml2Request = msg.get();
application.getServiceProvider().getTransactionLog()->write(*logout_event);
+ logout_event->m_saml2Request = nullptr;
}
auto_ptr_char dest(epit->getLocation());
else {
const char* returnloc = httpRequest.getParameter("return");
if (returnloc) {
- limitRelayState(m_log, application, httpRequest, returnloc);
- ret.second = httpResponse.sendRedirect(returnloc);
+ // Relative URLs get promoted, absolutes get validated.
+ if (*returnloc == '/') {
+ string loc(returnloc);
+ httpRequest.absolutize(loc);
+ ret.second = httpResponse.sendRedirect(loc.c_str());
+ }
+ else {
+ application.limitRedirect(httpRequest, returnloc);
+ ret.second = httpResponse.sendRedirect(returnloc);
+ }
ret.first = true;
}
- ret = sendLogoutPage(application, httpRequest, httpResponse, "global");
+ else {
+ ret = sendLogoutPage(application, httpRequest, httpResponse, "global");
+ }
}
}
string relayState;
const char* returnloc = httpRequest.getParameter("return");
if (returnloc) {
- limitRelayState(m_log, application, httpRequest, returnloc);
+ application.limitRedirect(httpRequest, returnloc);
relayState = returnloc;
+ httpRequest.absolutize(relayState);
+ cleanRelayState(application, httpRequest, httpResponse);
preserveRelayState(application, httpResponse, relayState);
}
msg->setNameID(nameid->cloneNameID());
}
- msg->setID(SAMLConfig::getConfig().generateIdentifier());
+ XMLCh* msgid = SAMLConfig::getConfig().generateIdentifier();
+ msg->setID(msgid);
+ XMLString::release(&msgid);
msg->setIssueInstant(time(nullptr));
+ if (m_async && encoder) {
+ msg->setExtensions(saml2p::ExtensionsBuilder::buildExtensions());
+ msg->getExtensions()->getUnknownXMLObjects().push_back(AsynchronousBuilder::buildAsynchronous());
+ }
+
return msg;
}