+ if (conf.isEnabled(SPConfig::Credentials)) {
+ m_credResolver.reset(
+ doChainedPlugins(xmlConf.CredentialResolverManager, "CredentialResolver", CHAINING_CREDENTIAL_RESOLVER, _CredentialResolver, e, log)
+ );
+ }
+
+ // Finally, load relying parties.
+ const DOMElement* child = XMLHelper::getFirstChildElement(e, RelyingParty);
+ while (child) {
+ if (child->hasAttributeNS(nullptr, saml2::Attribute::NAME_ATTRIB_NAME)) {
+ boost::shared_ptr<DOMPropertySet> rp(new DOMPropertySet());
+ rp->load(child, nullptr, this);
+ rp->setParent(this);
+ m_partyMap[child->getAttributeNS(nullptr, saml2::Attribute::NAME_ATTRIB_NAME)] = rp;
+ }
+ else if (child->hasAttributeNS(nullptr, _type)) {
+ string emtype(XMLHelper::getAttrString(child, nullptr, _type));
+ boost::shared_ptr<EntityMatcher> em(SAMLConfig::getConfig().EntityMatcherManager.newPlugin(emtype, child));
+ boost::shared_ptr<DOMPropertySet> rp(new DOMPropertySet());
+ rp->load(child, nullptr, this);
+ rp->setParent(this);
+ m_partyVec.push_back(make_pair(em, rp));
+ }
+ child = XMLHelper::getNextSiblingElement(child, RelyingParty);
+ }
+ if (base && m_partyMap.empty() && m_partyVec.empty() && (!base->m_partyMap.empty() || !base->m_partyVec.empty())) {
+ // For inheritance of RPs to work, we have to pull them in to the override by cloning the DOM.
+ child = XMLHelper::getFirstChildElement(base->getElement(), RelyingParty);
+ while (child) {
+ if (child->hasAttributeNS(nullptr, saml2::Attribute::NAME_ATTRIB_NAME)) {
+ DOMElement* rpclone = static_cast<DOMElement*>(child->cloneNode(true));
+ boost::shared_ptr<DOMPropertySet> rp(new DOMPropertySet());
+ rp->load(rpclone, nullptr, this);
+ rp->setParent(this);
+ m_partyMap[rpclone->getAttributeNS(nullptr, saml2::Attribute::NAME_ATTRIB_NAME)] = rp;
+ }
+ else if (child->hasAttributeNS(nullptr, _type)) {
+ DOMElement* rpclone = static_cast<DOMElement*>(child->cloneNode(true));
+ string emtype(XMLHelper::getAttrString(rpclone, nullptr, _type));
+ boost::shared_ptr<EntityMatcher> em(SAMLConfig::getConfig().EntityMatcherManager.newPlugin(emtype, rpclone));
+ boost::shared_ptr<DOMPropertySet> rp(new DOMPropertySet());
+ rp->load(rpclone, nullptr, this);
+ rp->setParent(this);
+ m_partyVec.push_back(make_pair(em, rp));
+ }
+ child = XMLHelper::getNextSiblingElement(child, RelyingParty);
+ }
+ }
+#endif
+
+ // Out of process only, we register a listener endpoint.
+ if (!conf.isEnabled(SPConfig::InProcess)) {
+ ListenerService* listener = sp->getListenerService(false);
+ if (listener) {
+ string addr=string(getId()) + "::getHeaders::Application";
+ listener->regListener(addr.c_str(), this);
+ }
+ else {
+ log.info("no ListenerService available, Application remoting disabled");
+ }
+ }
+}
+
+XMLApplication::~XMLApplication()
+{
+ ListenerService* listener=getServiceProvider().getListenerService(false);
+ if (listener && SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess) && !SPConfig::getConfig().isEnabled(SPConfig::InProcess)) {
+ string addr=string(getId()) + "::getHeaders::Application";
+ listener->unregListener(addr.c_str(), this);
+ }
+}
+
+template <class T> T* XMLApplication::doChainedPlugins(
+ PluginManager<T,string,const DOMElement*>& pluginMgr,
+ const char* pluginType,
+ const char* chainingType,
+ const XMLCh* localName,
+ DOMElement* e,
+ Category& log,
+ const char* dummyType
+ )
+{
+ string t;
+ DOMElement* child = XMLHelper::getFirstChildElement(e, localName);
+ if (child) {
+ // Check for multiple.
+ if (XMLHelper::getNextSiblingElement(child, localName)) {
+ log.info("multiple %s plugins, wrapping in a chain", pluginType);
+ DOMElement* chain = child->getOwnerDocument()->createElementNS(nullptr, localName);
+ while (child) {
+ chain->appendChild(child);
+ child = XMLHelper::getFirstChildElement(e, localName);
+ }
+ t = chainingType;
+ child = chain;
+ e->appendChild(chain);
+ }
+ else {
+ // Only a single one.
+ t = XMLHelper::getAttrString(child, nullptr, _type);
+ }
+
+ try {
+ if (!t.empty()) {
+ log.info("building %s of type %s...", pluginType, t.c_str());
+ return pluginMgr.newPlugin(t.c_str(), child);
+ }
+ else {
+ throw ConfigurationException("$1 element had no type attribute.", params(1, pluginType));
+ }
+ }
+ catch (std::exception& ex) {
+ log.crit("error building %s: %s", pluginType, ex.what());
+ if (dummyType) {
+ // Install a dummy version as a safety valve.
+ log.crit("installing safe %s in place of failed version", pluginType);
+ return pluginMgr.newPlugin(dummyType, nullptr);