+ else {
+ // Use metadata to locate the IdP's SSO service.
+ MetadataProviderCriteria mc(app, entityID, &IDPSSODescriptor::ELEMENT_QNAME, samlconstants::SAML20P_NS);
+ entity = m->getEntityDescriptor(mc);
+ if (!entity.first) {
+ m_log.warn("unable to locate metadata for provider (%s)", entityID);
+ throw MetadataException("Unable to locate metadata for identity provider ($entityID)", namedparams(1, "entityID", entityID));
+ }
+ else if (!entity.second) {
+ m_log.log(getParent() ? Priority::INFO : Priority::WARN, "unable to locate SAML 2.0 identity provider role for provider (%s)", entityID);
+ if (getParent())
+ return make_pair(false, 0L);
+ throw MetadataException("Unable to locate SAML 2.0 identity provider role for provider ($entityID)", namedparams(1, "entityID", entityID));
+ }
+ else if (artifactInbound && !SPConfig::getConfig().getArtifactResolver()->isSupported(dynamic_cast<const SSODescriptorType&>(*entity.second))) {
+ m_log.warn("artifact binding selected for response, but identity provider lacks support");
+ if (getParent())
+ return make_pair(false, 0L);
+ throw MetadataException("Identity provider ($entityID) lacks SAML 2.0 artifact support.", namedparams(1, "entityID", entityID));
+ }
+
+ // Loop over the supportable outgoing bindings.
+ role = dynamic_cast<const IDPSSODescriptor*>(entity.second);
+ for (vector<string>::const_iterator b = m_bindings.begin(); b != m_bindings.end(); ++b) {
+ auto_ptr_XMLCh wideb(b->c_str());
+ if (ep=EndpointManager<SingleSignOnService>(role->getSingleSignOnServices()).getByBinding(wideb.get())) {
+ map< string,boost::shared_ptr<MessageEncoder> >::const_iterator enc = m_encoders.find(*b);
+ if (enc != m_encoders.end())
+ encoder = enc->second.get();
+ break;
+ }
+ }
+ if (!ep || !encoder) {
+ m_log.warn("unable to locate compatible SSO service for provider (%s)", entityID);
+ if (getParent())
+ return make_pair(false, 0L);
+ throw MetadataException("Unable to locate compatible SSO service for provider ($entityID)", namedparams(1, "entityID", entityID));
+ }