#include <shibsp/SPConfig.h>
#include <shibsp/SPRequest.h>
#include <shibsp/handler/AssertionConsumerService.h>
-#include <shibsp/handler/LogoutHandler.h>
+#include <shibsp/handler/LogoutInitiator.h>
#include <shibsp/handler/SessionInitiator.h>
#include <xmltooling/logging.h>
#include <xmltooling/util/DateTime.h>
{
public:
ADFSSessionInitiator(const DOMElement* e, const char* appId)
- : AbstractHandler(e, Category::getInstance(SHIBSP_LOGCAT".SessionInitiator.ADFS"), nullptr, &m_remapper), m_appId(appId), m_binding(WSFED_NS) {
+ : AbstractHandler(e, Category::getInstance(SHIBSP_LOGCAT".SessionInitiator.ADFS"), nullptr, &m_remapper), m_appId(appId), m_binding(WSFED_NS) {
// If Location isn't set, defer address registration until the setParent call.
pair<bool,const char*> loc = getString("Location");
if (loc.first) {
#endif
};
- class SHIBSP_DLLLOCAL ADFSLogoutInitiator : public AbstractHandler, public LogoutHandler
+ class SHIBSP_DLLLOCAL ADFSLogoutInitiator : public AbstractHandler, public LogoutInitiator
{
public:
ADFSLogoutInitiator(const DOMElement* e, const char* appId)
void receive(DDF& in, ostream& out);
pair<bool,long> run(SPRequest& request, bool isHandler=true) const;
-#ifndef SHIBSP_LITE
- const char* getType() const {
- return "LogoutInitiator";
- }
-#endif
const XMLCh* getProtocolFamily() const {
return m_binding.get();
}
request.log(SPRequest::SPWarn, "invalid acsIndex property, using default ACS location");
}
if (!ACS) {
- const vector<const Handler*>& endpoints = app.getAssertionConsumerServicesByBinding(m_binding.get());
- if (endpoints.empty()) {
+ ACS = app.getAssertionConsumerServiceByBinding(WSFED_NS);
+ if (!ACS) {
m_log.error("unable to locate a compatible ACS");
throw ConfigurationException("Unable to locate an ADFS-compatible ACS in the configuration.");
}
- ACS = endpoints.front();
}
}
for (vector< pair<string,string> >::const_iterator i = m_unsetHeaders.begin(); i!=m_unsetHeaders.end(); ++i)
request.clearHeader(i->first.c_str(), i->second.c_str());
}
+
+const Handler* Application::getAssertionConsumerServiceByBinding(const char* binding) const
+{
+ auto_ptr_XMLCh b(binding);
+ const vector<const Handler*>& handlers = getAssertionConsumerServicesByBinding(b.get());
+ return handlers.empty() ? nullptr : handlers.front();
+}
virtual const Handler* getAssertionConsumerServiceByIndex(unsigned short index) const=0;
/**
+ * Returns an AssertionConsumerService Handler that supports
+ * a particular protocol binding.
+ *
+ * @param binding a protocol binding identifier
+ * @return a matching AssertionConsumerService, or nullptr
+ */
+ virtual const Handler* getAssertionConsumerServiceByBinding(const char* binding) const;
+
+ /**
+ * @deprecated
* Returns one or more AssertionConsumerService Handlers that support
* a particular protocol binding.
*
handler/AssertionConsumerService.h \
handler/Handler.h \
handler/LogoutHandler.h \
+ handler/LogoutInitiator.h \
handler/RemotedHandler.h \
handler/SessionInitiator.h
handler/impl/FormSessionInitiator.cpp \
handler/impl/LocalLogoutInitiator.cpp \
handler/impl/LogoutHandler.cpp \
+ handler/impl/LogoutInitiator.cpp \
handler/impl/MetadataGenerator.cpp \
handler/impl/RemotedHandler.cpp \
handler/impl/StatusHandler.cpp \
#include "SPConfig.h"
#include "TransactionLog.h"
#include "attribute/Attribute.h"
+#include "handler/LogoutInitiator.h"
#include "handler/SessionInitiator.h"
#include "remoting/ListenerService.h"
registerAttributeFactories();
registerHandlers();
+ registerLogoutInitiators();
registerSessionInitiators();
registerServiceProviders();
#if defined (_MSC_VER)
#pragma warning( pop )
#endif
-
- /** LogoutInitiator that iterates through a set of protocol-specific versions. */
- #define CHAINING_LOGOUT_INITIATOR "Chaining"
-
- /** LogoutInitiator that supports SAML 2.0 LogoutRequests. */
- #define SAML2_LOGOUT_INITIATOR "SAML2"
-
- /** LogoutInitiator that supports local-only logout. */
- #define LOCAL_LOGOUT_INITIATOR "Local"
-
};
#endif /* __shibsp_logout_h__ */
--- /dev/null
+/*\r
+ * Copyright 2010 Internet2\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/**\r
+ * @file shibsp/handler/LogoutInitiator.h\r
+ * \r
+ * Pluggable runtime functionality that handles initiating logout.\r
+ */\r
+\r
+#ifndef __shibsp_logoutinitiator_h__\r
+#define __shibsp_logoutinitiator_h__\r
+\r
+#include <shibsp/handler/LogoutHandler.h>\r
+\r
+namespace shibsp {\r
+\r
+ /**\r
+ * Pluggable runtime functionality that handles initiating logout.\r
+ */\r
+ class SHIBSP_API LogoutInitiator : public LogoutHandler\r
+ {\r
+ protected:\r
+ LogoutInitiator();\r
+ public:\r
+ virtual ~LogoutInitiator();\r
+\r
+#ifndef SHIBSP_LITE\r
+ const char* getType() const;\r
+#endif\r
+ };\r
+ \r
+ /** Registers LogoutInitiator implementations. */\r
+ void SHIBSP_API registerLogoutInitiators();\r
+\r
+ /** LogoutInitiator that iterates through a set of protocol-specific versions. */\r
+ #define CHAINING_LOGOUT_INITIATOR "Chaining"\r
+\r
+ /** LogoutInitiator that supports SAML 2.0 LogoutRequests. */\r
+ #define SAML2_LOGOUT_INITIATOR "SAML2"\r
+\r
+ /** LogoutInitiator that supports local-only logout. */\r
+ #define LOCAL_LOGOUT_INITIATOR "Local"\r
+};\r
+\r
+#endif /* __shibsp_logoutinitiator_h__ */\r
* Pluggable runtime functionality that handles initiating sessions.
*/
-#ifndef __shibsp_initiator_h__
-#define __shibsp_initiator_h__
+#ifndef __shibsp_sesinitiator_h__
+#define __shibsp_sesinitiator_h__
#include <shibsp/handler/Handler.h>
+#include <map>
#include <set>
#include <string>
/**
* Indicates the set of optional settings supported by the handler.
*
- * @return an array of the optional settings supported
+ * @return a set of the optional settings supported
*/
virtual const std::set<std::string>& getSupportedOptions() const;
#define COOKIE_SESSION_INITIATOR "Cookie"
};
-#endif /* __shibsp_initiator_h__ */
+#endif /* __shibsp_sesinitiator_h__ */
using namespace std;
namespace shibsp {
+
SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<const DOMElement*,const char*> >::Factory SAML1ConsumerFactory;
SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<const DOMElement*,const char*> >::Factory SAML2ConsumerFactory;
SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<const DOMElement*,const char*> >::Factory SAML2ArtifactResolutionFactory;
- SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<const DOMElement*,const char*> >::Factory ChainingLogoutInitiatorFactory;
- SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<const DOMElement*,const char*> >::Factory LocalLogoutInitiatorFactory;
- SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<const DOMElement*,const char*> >::Factory SAML2LogoutInitiatorFactory;
SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<const DOMElement*,const char*> >::Factory SAML2LogoutFactory;
SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<const DOMElement*,const char*> >::Factory SAML2NameIDMgmtFactory;
SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<const DOMElement*,const char*> >::Factory AssertionLookupFactory;
conf.HandlerManager.registerFactory(STATUS_HANDLER, StatusHandlerFactory);
conf.HandlerManager.registerFactory(SESSION_HANDLER, SessionHandlerFactory);
- conf.LogoutInitiatorManager.registerFactory(CHAINING_LOGOUT_INITIATOR, ChainingLogoutInitiatorFactory);
- conf.LogoutInitiatorManager.registerFactory(LOCAL_LOGOUT_INITIATOR, LocalLogoutInitiatorFactory);
- conf.LogoutInitiatorManager.registerFactory(SAML2_LOGOUT_INITIATOR, SAML2LogoutInitiatorFactory);
conf.SingleLogoutServiceManager.registerFactory(SAML20_BINDING_SOAP, SAML2LogoutFactory);
conf.SingleLogoutServiceManager.registerFactory(SAML20_BINDING_HTTP_REDIRECT, SAML2LogoutFactory);
conf.SingleLogoutServiceManager.registerFactory(SAML20_BINDING_HTTP_POST, SAML2LogoutFactory);
#include "internal.h"
#include "exceptions.h"
#include "handler/AbstractHandler.h"
-#include "handler/LogoutHandler.h"
+#include "handler/LogoutInitiator.h"
#include "util/SPConstants.h"
#include <xercesc/util/XMLUniDefs.hpp>
#pragma warning( disable : 4250 )
#endif
- class SHIBSP_DLLLOCAL ChainingLogoutInitiator : public AbstractHandler, public LogoutHandler
+ class SHIBSP_DLLLOCAL ChainingLogoutInitiator : public AbstractHandler, public LogoutInitiator
{
public:
ChainingLogoutInitiator(const DOMElement* e, const char* appId);
pair<bool,long> run(SPRequest& request, bool isHandler=true) const;
#ifndef SHIBSP_LITE
- const char* getType() const {
- return "LogoutInitiator";
- }
-
void generateMetadata(opensaml::saml2md::SPSSODescriptor& role, const char* handlerURL) const {
for (vector<Handler*>::const_iterator i = m_handlers.begin(); i!=m_handlers.end(); ++i)
(*i)->generateMetadata(role, handlerURL);
SPConfig& conf = SPConfig::getConfig();
// Load up the chain of handlers.
- e = e ? XMLHelper::getFirstChildElement(e, _LogoutInitiator) : nullptr;
+ e = XMLHelper::getFirstChildElement(e, _LogoutInitiator);
while (e) {
- auto_ptr_char type(e->getAttributeNS(nullptr,_type));
- if (type.get() && *(type.get())) {
+ string t(XMLHelper::getAttrString(e, nullptr, _type));
+ if (!t.empty()) {
try {
- m_handlers.push_back(conf.LogoutInitiatorManager.newPlugin(type.get(),make_pair(e, appId)));
+ m_handlers.push_back(conf.LogoutInitiatorManager.newPlugin(t.c_str(), make_pair(e, appId)));
m_handlers.back()->setParent(this);
}
catch (exception& ex) {
#include "SessionCache.h"
#include "SPRequest.h"
#include "handler/AbstractHandler.h"
-#include "handler/LogoutHandler.h"
+#include "handler/LogoutInitiator.h"
using namespace shibsp;
using namespace xmltooling;
#pragma warning( disable : 4250 )
#endif
- class SHIBSP_DLLLOCAL LocalLogoutInitiator : public AbstractHandler, public LogoutHandler
+ class SHIBSP_DLLLOCAL LocalLogoutInitiator : public AbstractHandler, public LogoutInitiator
{
public:
LocalLogoutInitiator(const DOMElement* e, const char* appId);
void setParent(const PropertySet* parent);
pair<bool,long> run(SPRequest& request, bool isHandler=true) const;
-#ifndef SHIBSP_LITE
- const char* getType() const {
- return "LogoutInitiator";
- }
-#endif
-
private:
string m_appId;
};
--- /dev/null
+/*\r
+ * Copyright 2010 Internet2\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/**\r
+ * LogoutInitiator.cpp\r
+ * \r
+ * Pluggable runtime functionality that handles initiating logout.\r
+ */\r
+\r
+#include "internal.h"\r
+#include "handler/LogoutInitiator.h"\r
+\r
+using namespace shibsp;\r
+using namespace xmltooling;\r
+using namespace std;\r
+\r
+namespace shibsp {\r
+ SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<const DOMElement*,const char*> >::Factory ChainingLogoutInitiatorFactory;\r
+ SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<const DOMElement*,const char*> >::Factory SAML2LogoutInitiatorFactory;\r
+ SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<const DOMElement*,const char*> >::Factory LocalLogoutInitiatorFactory;\r
+};\r
+\r
+void SHIBSP_API shibsp::registerLogoutInitiators()\r
+{\r
+ SPConfig& conf=SPConfig::getConfig();\r
+ conf.LogoutInitiatorManager.registerFactory(CHAINING_LOGOUT_INITIATOR, ChainingLogoutInitiatorFactory);\r
+ conf.LogoutInitiatorManager.registerFactory(SAML2_LOGOUT_INITIATOR, SAML2LogoutInitiatorFactory);\r
+ conf.LogoutInitiatorManager.registerFactory(LOCAL_LOGOUT_INITIATOR, LocalLogoutInitiatorFactory);\r
+}\r
+\r
+LogoutInitiator::LogoutInitiator()\r
+{\r
+}\r
+\r
+LogoutInitiator::~LogoutInitiator()\r
+{\r
+}\r
+\r
+#ifndef SHIBSP_LITE\r
+const char* LogoutInitiator::getType() const\r
+{\r
+ return "LogoutInitiator";\r
+}\r
+#endif\r
#include "ServiceProvider.h"
#include "SessionCache.h"
#include "handler/AbstractHandler.h"
-#include "handler/LogoutHandler.h"
+#include "handler/LogoutInitiator.h"
#ifndef SHIBSP_LITE
# include "binding/SOAPClient.h"
#pragma warning( disable : 4250 )
#endif
- class SHIBSP_DLLLOCAL SAML2LogoutInitiator : public AbstractHandler, public LogoutHandler
+ class SHIBSP_DLLLOCAL SAML2LogoutInitiator : public AbstractHandler, public LogoutInitiator
{
public:
SAML2LogoutInitiator(const DOMElement* e, const char* appId);
void receive(DDF& in, ostream& out);
pair<bool,long> run(SPRequest& request, bool isHandler=true) const;
-#ifndef SHIBSP_LITE
- const char* getType() const {
- return "LogoutInitiator";
- }
-#endif
const XMLCh* getProtocolFamily() const {
return samlconstants::SAML20P_NS;
}
using namespace opensaml::saml2md;
#else
# include "lite/SAMLConstants.h"
-#include <xercesc/util/XMLUniDefs.hpp>
+# include <xercesc/util/XMLUniDefs.hpp>
#endif
using namespace shibsp;
if (!ACS) {
if (ECP) {
- const vector<const Handler*>& handlers = app.getAssertionConsumerServicesByBinding(m_paosBinding.get());
- if (handlers.empty())
+ ACS = app.getAssertionConsumerServiceByBinding(samlconstants::SAML20_BINDING_PAOS);
+ if (!ACS)
throw ConfigurationException("Unable to locate PAOS response endpoint.");
- ACS = handlers.front();
}
else {
+ // Try fixed index property, or incoming binding set, or default, in order.
pair<bool,unsigned int> index = getUnsignedInt("acsIndex", request, HANDLER_PROPERTY_MAP|HANDLER_PROPERTY_FIXED);
if (index.first) {
ACS = app.getAssertionConsumerServiceByIndex(index.second);
if (!ACS)
request.log(SPRequest::SPWarn, "invalid acsIndex property, using default ACS location");
}
+ /*
+ for (vector<string>::const_iterator b = m_incomingBindings.begin(); !ACS && b != m_incomingBindings.end(); ++b) {
+ ACS = app.getAssertionConsumerServiceByBinding(b->c_str());
+ if (ACS && !XMLString::equals(getProtocolFamily(), ACS->getProtocolFamily()))
+ ACS = nullptr;
+ }
+ */
if (!ACS)
ACS = app.getDefaultAssertionConsumerService();
}
// Since we're not passing by index, we need to fully compute the return URL.
if (!ACS) {
+ // Try fixed index property, or incoming binding set, or default, in order.
pair<bool,unsigned int> index = getUnsignedInt("acsIndex", request, HANDLER_PROPERTY_MAP|HANDLER_PROPERTY_FIXED);
if (index.first) {
ACS = app.getAssertionConsumerServiceByIndex(index.second);
if (!ACS)
request.log(SPRequest::SPWarn, "invalid acsIndex property, using default ACS location");
}
+ /*
+ for (vector<string>::const_iterator b = m_incomingBindings.begin(); !ACS && b != m_incomingBindings.end(); ++b) {
+ ACS = app.getAssertionConsumerServiceByBinding(b->c_str());
+ if (ACS && !XMLString::equals(getProtocolFamily(), ACS->getProtocolFamily()))
+ ACS = nullptr;
+ }
+ */
if (!ACS)
ACS = app.getDefaultAssertionConsumerService();
}
// Since we're not passing by index, we need to fully compute the return URL.
if (!ACS) {
+ // Try fixed index property, or incoming binding set, or default, in order.
pair<bool,unsigned int> index = getUnsignedInt("acsIndex", request, HANDLER_PROPERTY_MAP|HANDLER_PROPERTY_FIXED);
if (index.first) {
ACS = app.getAssertionConsumerServiceByIndex(index.second);
if (!ACS)
request.log(SPRequest::SPWarn, "invalid acsIndex property, using default ACS location");
}
+ /*
+ for (vector<string>::const_iterator b = m_incomingBindings.begin(); !ACS && b != m_incomingBindings.end(); ++b) {
+ ACS = app.getAssertionConsumerServiceByBinding(b->c_str());
+ if (ACS && !XMLString::equals(getProtocolFamily(), ACS->getProtocolFamily()))
+ ACS = nullptr;
+ }
+ */
if (!ACS)
ACS = app.getDefaultAssertionConsumerService();
}
const SessionInitiator* getSessionInitiatorById(const char* id) const;
const Handler* getDefaultAssertionConsumerService() const;
const Handler* getAssertionConsumerServiceByIndex(unsigned short index) const;
+ const Handler* getAssertionConsumerServiceByBinding(const char* binding) const;
const vector<const Handler*>& getAssertionConsumerServicesByBinding(const XMLCh* binding) const;
const Handler* getHandler(const char* path) const;
void getHandlers(vector<const Handler*>& handlers) const;
const Handler* m_acsDefault;
// maps binding strings to supporting consumer service(s)
- typedef map<xstring,vector<const Handler*> > ACSBindingMap;
+ typedef map< string,vector<const Handler*> > ACSBindingMap;
ACSBindingMap m_acsBindingMap;
// pointer to default session initiator
continue;
}
handler = conf.AssertionConsumerServiceManager.newPlugin(bindprop.c_str(), make_pair(child, getId()));
- // Map by binding (may be > 1 per binding, e.g. SAML 1.0 vs 1.1)
- m_acsBindingMap[handler->getXMLString("Binding").second].push_back(handler);
+ // Map by binding (may be > 1 per binding)
+ m_acsBindingMap[bindprop].push_back(handler);
m_acsIndexMap[handler->getUnsignedInt("index").second] = handler;
if (!hardACS) {
string addr=string(getId()) + "::getHeaders::Application";
listener->regListener(addr.c_str(),this);
}
- else
+ else {
log.info("no ListenerService available, Application remoting disabled");
+ }
}
}
catch (exception&) {
const Handler* XMLApplication::getAssertionConsumerServiceByIndex(unsigned short index) const
{
map<unsigned int,const Handler*>::const_iterator i=m_acsIndexMap.find(index);
- if (i!=m_acsIndexMap.end()) return i->second;
+ if (i != m_acsIndexMap.end()) return i->second;
return m_base ? m_base->getAssertionConsumerServiceByIndex(index) : nullptr;
}
-const vector<const Handler*>& XMLApplication::getAssertionConsumerServicesByBinding(const XMLCh* binding) const
+const Handler* XMLApplication::getAssertionConsumerServiceByBinding(const char* binding) const
{
ACSBindingMap::const_iterator i=m_acsBindingMap.find(binding);
- if (i!=m_acsBindingMap.end())
+ if (i != m_acsBindingMap.end()) return i->second.front();
+ return m_base ? m_base->getAssertionConsumerServiceByBinding(binding) : nullptr;
+}
+
+const vector<const Handler*>& XMLApplication::getAssertionConsumerServicesByBinding(const XMLCh* binding) const
+{
+ auto_ptr_char b(binding);
+ ACSBindingMap::const_iterator i=m_acsBindingMap.find(b.get());
+ if (i != m_acsBindingMap.end())
return i->second;
return m_base ? m_base->getAssertionConsumerServicesByBinding(binding) : g_noHandlers;
}
<ItemGroup>\r
<ClCompile Include="AbstractSPRequest.cpp" />\r
<ClCompile Include="Application.cpp" />\r
+ <ClCompile Include="handler\impl\LogoutInitiator.cpp" />\r
<ClCompile Include="ServiceProvider.cpp" />\r
<ClCompile Include="SPConfig.cpp" />\r
<ClCompile Include="util\CGIParser.cpp" />\r
<ClCompile Include="lite\SAMLConstants.cpp" />\r
</ItemGroup>\r
<ItemGroup>\r
+ <ClInclude Include="handler\LogoutInitiator.h" />\r
<ClInclude Include="remoting\impl\SocketListener.h" />\r
<ClInclude Include="AbstractSPRequest.h" />\r
<ClInclude Include="AccessControl.h" />\r
<ClCompile Include="lite\SAMLConstants.cpp">\r
<Filter>Source Files\lite</Filter>\r
</ClCompile>\r
+ <ClCompile Include="handler\impl\LogoutInitiator.cpp">\r
+ <Filter>Source Files\handler\impl</Filter>\r
+ </ClCompile>\r
</ItemGroup>\r
<ItemGroup>\r
<ClInclude Include="remoting\impl\SocketListener.h">\r
<ClInclude Include="lite\SAMLConstants.h">\r
<Filter>Header Files\lite</Filter>\r
</ClInclude>\r
+ <ClInclude Include="handler\LogoutInitiator.h">\r
+ <Filter>Header Files\handler</Filter>\r
+ </ClInclude>\r
</ItemGroup>\r
<ItemGroup>\r
<ResourceCompile Include="shibsp.rc">\r
<ItemGroup>\r
<ClCompile Include="AbstractSPRequest.cpp" />\r
<ClCompile Include="Application.cpp" />\r
+ <ClCompile Include="handler\impl\LogoutInitiator.cpp" />\r
<ClCompile Include="impl\XMLSecurityPolicyProvider.cpp" />\r
<ClCompile Include="ServiceProvider.cpp" />\r
<ClCompile Include="SPConfig.cpp" />\r
<ClCompile Include="handler\impl\WAYFSessionInitiator.cpp" />\r
</ItemGroup>\r
<ItemGroup>\r
+ <ClInclude Include="handler\LogoutInitiator.h" />\r
<ClInclude Include="remoting\impl\SocketListener.h" />\r
<ClInclude Include="AbstractSPRequest.h" />\r
<ClInclude Include="AccessControl.h" />\r
<ClCompile Include="impl\XMLSecurityPolicyProvider.cpp">\r
<Filter>Source Files\impl</Filter>\r
</ClCompile>\r
+ <ClCompile Include="handler\impl\LogoutInitiator.cpp">\r
+ <Filter>Source Files\handler\impl</Filter>\r
+ </ClCompile>\r
</ItemGroup>\r
<ItemGroup>\r
<ClInclude Include="remoting\impl\SocketListener.h">\r
<ClInclude Include="security\SecurityPolicyProvider.h">\r
<Filter>Header Files\security</Filter>\r
</ClInclude>\r
+ <ClInclude Include="handler\LogoutInitiator.h">\r
+ <Filter>Header Files\handler</Filter>\r
+ </ClInclude>\r
</ItemGroup>\r
<ItemGroup>\r
<ResourceCompile Include="shibsp.rc">\r