attrinclude_HEADERS = \
attribute/Attribute.h \
+ attribute/AttributeDecoder.h \
attribute/NameIDAttribute.h \
attribute/ScopedAttribute.h \
attribute/SimpleAttribute.h
SessionCache.cpp \
SPConfig.cpp \
attribute/Attribute.cpp \
+ attribute/SimpleAttributeDecoder.cpp \
+ attribute/ScopedAttributeDecoder.cpp \
binding/impl/SOAPClient.cpp \
impl/RemotedSessionCache.cpp \
impl/StorageServiceSessionCache.cpp \
#include "ServiceProvider.h"
#include "SessionCache.h"
#include "SPConfig.h"
+#include "attribute/AttributeDecoder.h"
#include "metadata/MetadataExt.h"
#include "remoting/ListenerService.h"
#include "security/PKIXTrustEngine.h"
-#include "attribute/SimpleAttribute.h"
-#include "attribute/ScopedAttribute.h"
-#include "attribute/NameIDAttribute.h"
-
#include <log4cpp/Category.hh>
#include <saml/SAMLConfig.h>
#include <xmltooling/util/NDC.h>
registerSessionCaches();
registerServiceProviders();
registerAttributeFactories();
+ registerAttributeDecoders();
log.info("library initialization complete");
return true;
delete m_serviceProvider;
m_serviceProvider = NULL;
- Attribute::deregisterFactories();
-
SingleLogoutServiceManager.deregisterFactories();
SessionInitiatorManager.deregisterFactories();
SessionCacheManager.deregisterFactories();
ManageNameIDServiceManager.deregisterFactories();
ListenerServiceManager.deregisterFactories();
HandlerManager.deregisterFactories();
+ Attribute::deregisterFactories();
+ AttributeDecoderManager.deregisterFactories();
AssertionConsumerServiceManager.deregisterFactories();
AccessControlManager.deregisterFactories();
namespace shibsp {
class SHIBSP_API AccessControl;
+ class SHIBSP_API AttributeDecoder;
class SHIBSP_API Handler;
class SHIBSP_API ListenerService;
class SHIBSP_API RequestMapper;
xmltooling::PluginManager<AccessControl,const xercesc::DOMElement*> AccessControlManager;
/**
+ * Manages factories for AttributeDecoder plugins.
+ */
+ xmltooling::PluginManager<AttributeDecoder,const xercesc::DOMElement*> AttributeDecoderManager;
+
+ /**
* Manages factories for Handler plugins that implement AssertionConsumerService functionality.
*/
xmltooling::PluginManager<Handler,const xercesc::DOMElement*> AssertionConsumerServiceManager;
* A resolved attribute.
*/
-
#include "internal.h"
+#include "attribute/AttributeDecoder.h"
#include "attribute/SimpleAttribute.h"
#include "attribute/ScopedAttribute.h"
#include "attribute/NameIDAttribute.h"
+#include <shibsp/SPConfig.h>
+
using namespace shibsp;
+using namespace xmltooling;
using namespace std;
namespace shibsp {
- Attribute* SimpleAttributeFactory(DDF& in) {
+ SHIBSP_DLLLOCAL Attribute* SimpleAttributeFactory(DDF& in) {
return new SimpleAttribute(in);
}
- Attribute* ScopedAttributeFactory(DDF& in) {
+ SHIBSP_DLLLOCAL Attribute* ScopedAttributeFactory(DDF& in) {
return new ScopedAttribute(in);
}
- Attribute* NameIDAttributeFactory(DDF& in) {
+ SHIBSP_DLLLOCAL Attribute* NameIDAttributeFactory(DDF& in) {
return new NameIDAttribute(in);
}
+ SHIBSP_DLLLOCAL PluginManager<AttributeDecoder,const DOMElement*>::Factory SimpleAttributeDecoderFactory;
+ SHIBSP_DLLLOCAL PluginManager<AttributeDecoder,const DOMElement*>::Factory ScopedAttributeDecoderFactory;
+ //SHIBSP_DLLLOCAL PluginManager<AttributeDecoder,const DOMElement*>::Factory NameIDAttributeDecoderFactory;
};
+void shibsp::registerAttributeDecoders()
+{
+ SPConfig& conf = SPConfig::getConfig();
+ conf.AttributeDecoderManager.registerFactory(SIMPLE_ATTRIBUTE_DECODER, SimpleAttributeDecoderFactory);
+ conf.AttributeDecoderManager.registerFactory(SCOPED_ATTRIBUTE_DECODER, ScopedAttributeDecoderFactory);
+ //conf.AttributeDecoderManager.registerFactory(NAMEID_ATTRIBUTE_DECODER, NameIDAttributeDecoderFactory);
+}
+
void shibsp::registerAttributeFactories()
{
Attribute::registerFactory("", SimpleAttributeFactory);
--- /dev/null
+/*
+ * Copyright 2001-2007 Internet2
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file shibsp/attribute/AttributeDecoder.h
+ *
+ * Decodes SAML NameID/Attribute objects into resolved Attributes.
+ */
+
+#ifndef __shibsp_attrdecoder_h__
+#define __shibsp_attrdecoder_h__
+
+#include <shibsp/attribute/Attribute.h>
+#include <xmltooling/XMLObject.h>
+
+namespace shibsp {
+
+ /**
+ * Decodes XML objects into resolved Attributes.
+ */
+ class SHIBSP_API AttributeDecoder
+ {
+ MAKE_NONCOPYABLE(AttributeDecoder);
+ protected:
+ AttributeDecoder() {}
+ public:
+ virtual ~AttributeDecoder() {}
+
+ /**
+ * Decodes an XMLObject into a resolved Attribute.
+ *
+ * @param id ID of resolved attribute
+ * @param xmlObject XMLObject to decode
+ * @return a resolved Attribute
+ */
+ virtual Attribute* decode(const char* id, const xmltooling::XMLObject* xmlObject) const=0;
+ };
+
+ /** Decodes SimpleAttributes */
+ #define SIMPLE_ATTRIBUTE_DECODER "Simple"
+
+ /** Decodes ScopedAttributes */
+ #define SCOPED_ATTRIBUTE_DECODER "Scoped"
+
+ /** Decodes NameIDAttributes */
+ #define NAMEID_ATTRIBUTE_DECODER "NameID"
+
+ /** Registers built-in AttributeDecoders into the runtime. */
+ void registerAttributeDecoders();
+};
+
+#endif /* __shibsp_attrdecoder_h__ */
--- /dev/null
+/*\r
+ * Copyright 2001-2007 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
+ * ScopedAttributeDecoder.cpp\r
+ * \r
+ * Decodes SAML into ScopedAttributes\r
+ */\r
+\r
+#include "internal.h"\r
+#include "attribute/AttributeDecoder.h"\r
+#include "attribute/ScopedAttribute.h"\r
+\r
+#include <log4cpp/Category.hh>\r
+#include <saml/saml1/core/Assertions.h>\r
+#include <saml/saml2/core/Assertions.h>\r
+\r
+using namespace shibsp;\r
+using namespace opensaml::saml1;\r
+using namespace opensaml::saml2;\r
+using namespace xmltooling;\r
+using namespace log4cpp;\r
+using namespace std;\r
+\r
+namespace shibsp {\r
+ class ScopedAttributeDecoder : virtual public AttributeDecoder\r
+ {\r
+ public:\r
+ ScopedAttributeDecoder(const DOMElement* e) {}\r
+ ~ScopedAttributeDecoder() {}\r
+\r
+ shibsp::Attribute* decode(const char* id, const XMLObject* xmlObject) const;\r
+ };\r
+\r
+ AttributeDecoder* SHIBSP_DLLLOCAL ScopedAttributeDecoderFactory(const DOMElement* const & e)\r
+ {\r
+ return new ScopedAttributeDecoder(e);\r
+ }\r
+\r
+ static const XMLCh Scope[] = UNICODE_LITERAL_5(S,c,o,p,e);\r
+};\r
+\r
+shibsp::Attribute* ScopedAttributeDecoder::decode(const char* id, const XMLObject* xmlObject) const\r
+{\r
+ char* val;\r
+ char* scope;\r
+ const XMLCh* xmlscope;\r
+ QName scopeqname(NULL,Scope);\r
+ auto_ptr<ScopedAttribute> scoped(new ScopedAttribute(id));\r
+ vector< pair<string,string> >& dest = scoped->getValues();\r
+ vector<XMLObject*>::const_iterator v,stop;\r
+\r
+ Category& log = Category::getInstance(SHIBSP_LOGCAT".AttributeDecoder");\r
+ \r
+ if (xmlObject && XMLString::equals(opensaml::saml1::Attribute::LOCAL_NAME,xmlObject->getElementQName().getLocalPart())) {\r
+ const opensaml::saml2::Attribute* saml2attr = dynamic_cast<const opensaml::saml2::Attribute*>(xmlObject);\r
+ if (saml2attr) {\r
+ const vector<XMLObject*>& values = saml2attr->getAttributeValues();\r
+ v = values.begin();\r
+ stop = values.end();\r
+ if (log.isDebugEnabled()) {\r
+ auto_ptr_char n(saml2attr->getName());\r
+ log.debug("decoding ScopedAttribute (%s) from SAML 2 Attribute (%s) with %lu value(s)", id, n.get() ? n.get() : "unnamed", values.size());\r
+ }\r
+ }\r
+ else {\r
+ const opensaml::saml1::Attribute* saml1attr = dynamic_cast<const opensaml::saml1::Attribute*>(xmlObject);\r
+ if (saml1attr) {\r
+ const vector<XMLObject*>& values = saml2attr->getAttributeValues();\r
+ v = values.begin();\r
+ stop = values.end();\r
+ if (log.isDebugEnabled()) {\r
+ auto_ptr_char n(saml1attr->getAttributeName());\r
+ log.debug("decoding ScopedAttribute (%s) from SAML 1 Attribute (%s) with %lu value(s)", id, n.get() ? n.get() : "unnamed", values.size());\r
+ }\r
+ }\r
+ else {\r
+ log.warn("XMLObject type not recognized by ScopedAttributeDecoder, no values returned");\r
+ return NULL;\r
+ }\r
+ }\r
+\r
+ for (; v!=stop; ++v) {\r
+ if (!(*v)->hasChildren()) {\r
+ val = toUTF8((*v)->getTextContent());\r
+ if (val && *val) {\r
+ const AttributeExtensibleXMLObject* aexo=dynamic_cast<const AttributeExtensibleXMLObject*>(*v);\r
+ xmlscope = aexo->getAttribute(scopeqname);\r
+ if (xmlscope && *xmlscope) {\r
+ scope = toUTF8(xmlscope);\r
+ dest.push_back(make_pair(val,scope));\r
+ delete[] scope;\r
+ }\r
+ else {\r
+ scope = strchr(val, '@');\r
+ if (scope) {\r
+ *scope++ = 0;\r
+ if (*scope)\r
+ dest.push_back(make_pair(val,scope));\r
+ else\r
+ log.warn("ignoring unscoped AttributeValue");\r
+ }\r
+ else {\r
+ log.warn("ignoring unscoped AttributeValue");\r
+ }\r
+ }\r
+ }\r
+ else {\r
+ log.warn("skipping empty AttributeValue");\r
+ }\r
+ delete[] val;\r
+ }\r
+ else {\r
+ log.warn("skipping complex AttributeValue");\r
+ }\r
+ }\r
+\r
+ return dest.empty() ? NULL : scoped.release();\r
+ }\r
+\r
+ const NameID* saml2name = dynamic_cast<const NameID*>(xmlObject);\r
+ if (saml2name) {\r
+ if (log.isDebugEnabled()) {\r
+ auto_ptr_char f(saml2name->getFormat());\r
+ log.debug("decoding ScopedAttribute (%s) from SAML 2 NameID with Format (%s)", id, f.get() ? f.get() : "unspecified");\r
+ }\r
+ val = toUTF8(saml2name->getName());\r
+ }\r
+ else {\r
+ const NameIdentifier* saml1name = dynamic_cast<const NameIdentifier*>(xmlObject);\r
+ if (saml1name) {\r
+ if (log.isDebugEnabled()) {\r
+ auto_ptr_char f(saml1name->getFormat());\r
+ log.debug("decoding ScopedAttribute (%s) from SAML 1 NameIdentifier with Format (%s)", id, f.get() ? f.get() : "unspecified");\r
+ }\r
+ val = toUTF8(saml1name->getName());\r
+ }\r
+ else {\r
+ log.warn("XMLObject type not recognized by ScopedAttributeDecoder, no values returned");\r
+ return NULL;\r
+ }\r
+ }\r
+\r
+ if (val && *val && *val!='@') {\r
+ scope = strchr(val, '@');\r
+ if (scope) {\r
+ *scope++ = 0;\r
+ if (*scope)\r
+ dest.push_back(make_pair(val,scope));\r
+ else\r
+ log.warn("ignoring NameID with no scope");\r
+ }\r
+ else {\r
+ log.warn("ignoring NameID with no scope delimiter (@)");\r
+ }\r
+ }\r
+ else {\r
+ log.warn("ignoring empty NameID");\r
+ }\r
+ delete[] val;\r
+ return dest.empty() ? NULL : scoped.release();\r
+}\r
--- /dev/null
+/*\r
+ * Copyright 2001-2007 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
+ * SimpleAttributeDecoder.cpp\r
+ * \r
+ * Decodes SAML into SimpleAttributes\r
+ */\r
+\r
+#include "internal.h"\r
+#include "attribute/AttributeDecoder.h"\r
+#include "attribute/SimpleAttribute.h"\r
+\r
+#include <log4cpp/Category.hh>\r
+#include <saml/saml1/core/Assertions.h>\r
+#include <saml/saml2/core/Assertions.h>\r
+\r
+using namespace shibsp;\r
+using namespace opensaml::saml1;\r
+using namespace opensaml::saml2;\r
+using namespace xmltooling;\r
+using namespace log4cpp;\r
+using namespace std;\r
+\r
+namespace shibsp {\r
+ class SimpleAttributeDecoder : virtual public AttributeDecoder\r
+ {\r
+ public:\r
+ SimpleAttributeDecoder(const DOMElement* e) {}\r
+ ~SimpleAttributeDecoder() {}\r
+\r
+ shibsp::Attribute* decode(const char* id, const XMLObject* xmlObject) const;\r
+ };\r
+\r
+ AttributeDecoder* SHIBSP_DLLLOCAL SimpleAttributeDecoderFactory(const DOMElement* const & e)\r
+ {\r
+ return new SimpleAttributeDecoder(e);\r
+ }\r
+};\r
+\r
+shibsp::Attribute* SimpleAttributeDecoder::decode(const char* id, const XMLObject* xmlObject) const\r
+{\r
+ char* val;\r
+ auto_ptr<SimpleAttribute> simple(new SimpleAttribute(id));\r
+ vector<string>& dest = simple->getValues();\r
+ vector<XMLObject*>::const_iterator v,stop;\r
+\r
+ Category& log = Category::getInstance(SHIBSP_LOGCAT".AttributeDecoder");\r
+\r
+ if (xmlObject && XMLString::equals(opensaml::saml1::Attribute::LOCAL_NAME,xmlObject->getElementQName().getLocalPart())) {\r
+ const opensaml::saml2::Attribute* saml2attr = dynamic_cast<const opensaml::saml2::Attribute*>(xmlObject);\r
+ if (saml2attr) {\r
+ const vector<XMLObject*>& values = saml2attr->getAttributeValues();\r
+ v = values.begin();\r
+ stop = values.end();\r
+ if (log.isDebugEnabled()) {\r
+ auto_ptr_char n(saml2attr->getName());\r
+ log.debug("decoding SimpleAttribute (%s) from SAML 2 Attribute (%s) with %lu value(s)", id, n.get() ? n.get() : "unnamed", values.size());\r
+ }\r
+ }\r
+ else {\r
+ const opensaml::saml1::Attribute* saml1attr = dynamic_cast<const opensaml::saml1::Attribute*>(xmlObject);\r
+ if (saml1attr) {\r
+ const vector<XMLObject*>& values = saml2attr->getAttributeValues();\r
+ v = values.begin();\r
+ stop = values.end();\r
+ if (log.isDebugEnabled()) {\r
+ auto_ptr_char n(saml1attr->getAttributeName());\r
+ log.debug("decoding SimpleAttribute (%s) from SAML 1 Attribute (%s) with %lu value(s)", id, n.get() ? n.get() : "unnamed", values.size());\r
+ }\r
+ }\r
+ else {\r
+ log.warn("XMLObject type not recognized by SimpleAttributeDecoder, no values returned");\r
+ return NULL;\r
+ }\r
+ }\r
+\r
+ for (; v!=stop; ++v) {\r
+ if (!(*v)->hasChildren()) {\r
+ val = toUTF8((*v)->getTextContent());\r
+ if (val && *val)\r
+ dest.push_back(val);\r
+ else\r
+ log.warn("skipping empty AttributeValue");\r
+ delete[] val;\r
+ }\r
+ else {\r
+ log.warn("skipping complex AttributeValue");\r
+ }\r
+ }\r
+\r
+ return dest.empty() ? NULL : simple.release();\r
+ }\r
+\r
+ const NameID* saml2name = dynamic_cast<const NameID*>(xmlObject);\r
+ if (saml2name) {\r
+ if (log.isDebugEnabled()) {\r
+ auto_ptr_char f(saml2name->getFormat());\r
+ log.debug("decoding SimpleAttribute (%s) from SAML 2 NameID with Format (%s)", id, f.get() ? f.get() : "unspecified");\r
+ }\r
+ val = toUTF8(saml2name->getName());\r
+ }\r
+ else {\r
+ const NameIdentifier* saml1name = dynamic_cast<const NameIdentifier*>(xmlObject);\r
+ if (saml1name) {\r
+ if (log.isDebugEnabled()) {\r
+ auto_ptr_char f(saml1name->getFormat());\r
+ log.debug("decoding SimpleAttribute (%s) from SAML 1 NameIdentifier with Format (%s)", id, f.get() ? f.get() : "unspecified");\r
+ }\r
+ val = toUTF8(saml1name->getName());\r
+ }\r
+ else {\r
+ log.warn("XMLObject type not recognized by SimpleAttributeDecoder, no values returned");\r
+ return NULL;\r
+ }\r
+ }\r
+\r
+ if (val && *val)\r
+ dest.push_back(val);\r
+ else\r
+ log.warn("ignoring empty NameID");\r
+ delete[] val;\r
+ return dest.empty() ? NULL : simple.release();\r
+}\r
child = XMLHelper::getFirstChildElement(e,_MetadataProvider);\r
if (child) {\r
auto_ptr_char type(child->getAttributeNS(NULL,_type));\r
- log.info("building metadata provider of type %s...",type.get());\r
+ log.info("building MetadataProvider of type %s...",type.get());\r
try {\r
auto_ptr<MetadataProvider> mp(samlConf.MetadataProviderManager.newPlugin(type.get(),child));\r
mp->init();\r
m_metadata = mp.release();\r
}\r
catch (exception& ex) {\r
- log.crit("error building/initializing metadata provider: %s", ex.what());\r
+ log.crit("error building/initializing MetadataProvider: %s", ex.what());\r
}\r
}\r
}\r
child = XMLHelper::getFirstChildElement(e,_TrustEngine);\r
if (child) {\r
auto_ptr_char type(child->getAttributeNS(NULL,_type));\r
- log.info("building trust engine of type %s...",type.get());\r
+ log.info("building TrustEngine of type %s...",type.get());\r
try {\r
m_trust = xmlConf.TrustEngineManager.newPlugin(type.get(),child);\r
}\r
catch (exception& ex) {\r
- log.crit("error building trust engine: %s",ex.what());\r
+ log.crit("error building TrustEngine: %s",ex.what());\r
}\r
}\r
}\r
RelativePath=".\attribute\Attribute.cpp"\r
>\r
</File>\r
+ <File\r
+ RelativePath=".\attribute\ScopedAttributeDecoder.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\attribute\SimpleAttributeDecoder.cpp"\r
+ >\r
+ </File>\r
</Filter>\r
<Filter\r
Name="binding"\r