#include <shibsp/handler/AssertionConsumerService.h>
#include <shibsp/handler/LogoutHandler.h>
#include <shibsp/handler/SessionInitiator.h>
+#include <xmltooling/logging.h>
#include <xmltooling/util/NDC.h>
#include <xmltooling/util/URLEncoder.h>
#include <xmltooling/util/XMLHelper.h>
-#include <log4cpp/Category.hh>
#include <xercesc/util/XMLUniDefs.hpp>
#ifndef SHIBSP_LITE
#endif
using namespace shibsp;
using namespace opensaml;
+using namespace xmltooling::logging;
using namespace xmltooling;
using namespace xercesc;
-using namespace log4cpp;
using namespace std;
#define WSFED_NS "http://schemas.xmlsoap.org/ws/2003/07/secext"
namespace {
+#ifndef SHIBSP_LITE
+ class SHIBSP_DLLLOCAL ADFSDecoder : public MessageDecoder
+ {
+ auto_ptr_XMLCh m_ns;
+ public:
+ ADFSDecoder() : m_ns(WSTRUST_NS) {}
+ virtual ~ADFSDecoder() {}
+
+ XMLObject* decode(string& relayState, const GenericRequest& genericRequest, SecurityPolicy& policy) const;
+ };
+
+ MessageDecoder* ADFSDecoderFactory(const pair<const DOMElement*,const XMLCh*>& p)
+ {
+ return new ADFSDecoder();
+ }
+
+ class SHIBSP_DLLLOCAL ADFSMessageRule : public SecurityPolicyRule
+ {
+ public:
+ ADFSMessageRule(const DOMElement* e) : m_protocol(WSFED_NS) {}
+ virtual ~ADFSMessageRule() {}
+
+ const char* getType() const {
+ return "ADFSMessage";
+ }
+ void evaluate(const XMLObject& message, const GenericRequest* request, const XMLCh* protocol, SecurityPolicy& policy) const;
+
+ auto_ptr_XMLCh m_protocol;
+ };
+
+ SecurityPolicyRule* ADFSMessageRuleFactory(const DOMElement* const & e)
+ {
+ return new ADFSMessageRule(e);
+ }
+#endif
+
#if defined (_MSC_VER)
#pragma warning( push )
#pragma warning( disable : 4250 )
ADFSConsumer(const DOMElement* e, const char* appId)
: shibsp::AssertionConsumerService(e, appId, Category::getInstance(SHIBSP_LOGCAT".SSO.ADFS"))
#ifndef SHIBSP_LITE
- ,m_binding(WSFED_NS)
+ ,m_messageRule(e)
#endif
{}
virtual ~ADFSConsumer() {}
const PropertySet* settings,
const XMLObject& xmlObject
) const;
- auto_ptr_XMLCh m_binding;
+ ADFSMessageRule m_messageRule;
#endif
};
#pragma warning( pop )
#endif
-#ifndef SHIBSP_LITE
- class ADFSDecoder : public MessageDecoder
- {
- auto_ptr_XMLCh m_ns;
- public:
- ADFSDecoder() : m_ns(WSTRUST_NS) {}
- virtual ~ADFSDecoder() {}
-
- XMLObject* decode(string& relayState, const GenericRequest& genericRequest, SecurityPolicy& policy) const;
- };
-
- MessageDecoder* ADFSDecoderFactory(const pair<const DOMElement*,const XMLCh*>& p)
- {
- return new ADFSDecoder();
- }
-#endif
-
SessionInitiator* ADFSSessionInitiatorFactory(const pair<const DOMElement*,const char*>& p)
{
return new ADFSSessionInitiator(p.first, p.second);
conf.AssertionConsumerServiceManager.registerFactory(WSFED_NS, ADFSLogoutFactory);
#ifndef SHIBSP_LITE
SAMLConfig::getConfig().MessageDecoderManager.registerFactory(WSFED_NS, ADFSDecoderFactory);
+ SAMLConfig::getConfig().SecurityPolicyRuleManager.registerFactory("ADFSMessage", ADFSMessageRuleFactory);
XMLObjectBuilder::registerBuilder(QName(WSTRUST_NS,"RequestedSecurityToken"), new AnyElementBuilder());
- XMLObjectBuilder::registerBuilder(QName(WSTRUST_NS,"RequestedSecurityTokenResponse"), new AnyElementBuilder());
+ XMLObjectBuilder::registerBuilder(QName(WSTRUST_NS,"RequestSecurityTokenResponse"), new AnyElementBuilder());
#endif
return 0;
}
conf.AssertionConsumerServiceManager.deregisterFactory(WSFED_NS);
#ifndef SHIBSP_LITE
SAMLConfig::getConfig().MessageDecoderManager.deregisterFactory(WSFED_NS);
+ SAMLConfig::getConfig().SecurityPolicyRuleManager.deregisterFactory("ADFSMessage");
#endif
*/
}
if (!policy.getValidating())
SchemaValidators.validate(xmlObject.get());
- // Run through the policy.
- policy.evaluate(*xmlObject.get(), &genericRequest);
+ // Skip policy step here, there's no security in the wrapper.
+ // policy.evaluate(*xmlObject.get(), &genericRequest);
return xmlObject.release();
}
+void ADFSMessageRule::evaluate(const XMLObject& message, const GenericRequest* request, const XMLCh* protocol, SecurityPolicy& policy) const
+{
+ Category& log=Category::getInstance(SHIBSP_LOGCAT".SecurityPolicyRule.ADFSMessage");
+
+ if (!XMLString::equals(protocol, m_protocol.get()))
+ return;
+
+ const QName& q = message.getElementQName();
+ if (!XMLString::equals(q.getNamespaceURI(), samlconstants::SAML1_NS) ||
+ !XMLString::equals(q.getLocalPart(), saml1::Assertion::LOCAL_NAME))
+ return;
+
+ try {
+ const saml1::Assertion& token = dynamic_cast<const saml1::Assertion&>(message);
+ policy.setMessageID(token.getAssertionID());
+ policy.setIssueInstant(token.getIssueInstantEpoch());
+
+ log.debug("extracting issuer from message");
+
+ policy.setIssuer(token.getIssuer());
+
+ if (log.isDebugEnabled()) {
+ auto_ptr_char iname(token.getIssuer());
+ log.debug("message from (%s)", iname.get());
+ }
+
+ if (policy.getIssuerMetadata()) {
+ log.debug("metadata for issuer already set, leaving in place");
+ return;
+ }
+
+ if (policy.getMetadataProvider() && policy.getRole()) {
+ log.debug("searching metadata for message issuer...");
+ const EntityDescriptor* entity = policy.getMetadataProvider()->getEntityDescriptor(token.getIssuer());
+ if (!entity) {
+ auto_ptr_char temp(token.getIssuer());
+ log.warn("no metadata found, can't establish identity of issuer (%s)", temp.get());
+ return;
+ }
+
+ log.debug("matched message issuer against metadata, searching for applicable role...");
+ const RoleDescriptor* roledesc=entity->getRoleDescriptor(*policy.getRole(), m_protocol.get());
+ if (!roledesc) {
+ log.warn("unable to find compatible role (%s) in metadata", policy.getRole()->toString().c_str());
+ return;
+ }
+ policy.setIssuerMetadata(roledesc);
+ }
+ }
+ catch (bad_cast&) {
+ // Just trap it.
+ log.warn("caught a bad_cast while examining message");
+ }
+}
+
string ADFSConsumer::implementProtocol(
const Application& application,
const HTTPRequest& httpRequest,
// Run the policy over the assertion. Handles issuer consistency, replay, freshness,
// and signature verification, assuming the relevant rules are configured.
- policy.evaluate(*token);
+ policy.getRules().insert(policy.getRules().begin(), &m_messageRule);
+ policy.evaluate(*token, NULL, m_messageRule.m_protocol.get());
// If no security is in place now, we kick it.
if (!policy.isSecure())
// We've successfully "accepted" the SSO token.
// To complete processing, we need to extract and resolve attributes and then create the session.
- multimap<string,Attribute*> resolvedAttributes;
+ vector<Attribute*> resolvedAttributes;
AttributeExtractor* extractor = application.getAttributeExtractor();
if (extractor) {
m_log.debug("extracting pushed attributes...");
catch (exception& ex) {
m_log.error("caught exception filtering attributes: %s", ex.what());
m_log.error("dumping extracted attributes due to filtering exception");
- for_each(resolvedAttributes.begin(), resolvedAttributes.end(), cleanup_pair<string,shibsp::Attribute>());
+ for_each(resolvedAttributes.begin(), resolvedAttributes.end(), xmltooling::cleanup<shibsp::Attribute>());
resolvedAttributes.clear();
}
}
resolveAttributes(
application,
issuerMetadata,
- m_binding.get(),
+ m_messageRule.m_protocol.get(),
nameid.get(),
ssoStatement->getAuthenticationMethod(),
NULL,
tokens.insert(tokens.end(), ctx->getResolvedAssertions().begin(), ctx->getResolvedAssertions().end());
// Copy over new attributes, and transfer ownership.
- resolvedAttributes.insert(ctx->getResolvedAttributes().begin(), ctx->getResolvedAttributes().end());
+ resolvedAttributes.insert(resolvedAttributes.end(), ctx->getResolvedAttributes().begin(), ctx->getResolvedAttributes().end());
ctx->getResolvedAttributes().clear();
}
application,
httpRequest.getRemoteAddr().c_str(),
issuerMetadata,
- m_binding.get(),
+ m_messageRule.m_protocol.get(),
nameid.get(),
ssoStatement->getAuthenticationInstant() ? ssoStatement->getAuthenticationInstant()->getRawData() : NULL,
NULL,
&tokens,
&resolvedAttributes
);
- for_each(resolvedAttributes.begin(), resolvedAttributes.end(), cleanup_pair<string,Attribute>());
+ for_each(resolvedAttributes.begin(), resolvedAttributes.end(), xmltooling::cleanup<shibsp::Attribute>());
return key;
}
catch (exception&) {
- for_each(resolvedAttributes.begin(), resolvedAttributes.end(), cleanup_pair<string,Attribute>());
+ for_each(resolvedAttributes.begin(), resolvedAttributes.end(), xmltooling::cleanup<shibsp::Attribute>());
throw;
}
}