void extractAttributes(
const Application& application, const char* assertingParty, const saml2::Attribute& attr, vector<Attribute*>& attributes
) const;
+ void extractAttributes(
+ const Application& application, const char* assertingParty, const Extensions& ext, vector<Attribute*>& attributes
+ ) const;
void getAttributeIds(vector<string>& attributes) const {
attributes.insert(attributes.end(), m_attributeIds.begin(), m_attributeIds.end());
}
}
+void XMLExtractorImpl::extractAttributes(
+ const Application& application, const char* assertingParty, const Extensions& ext, vector<Attribute*>& attributes
+ ) const
+{
+ const vector<XMLObject*> exts = ext.getUnknownXMLObjects();
+ for (vector<XMLObject*>::const_iterator i = exts.begin(); i!=exts.end(); ++i) {
+ const saml2::Attribute* attr = dynamic_cast<const saml2::Attribute*>(*i);
+ if (attr)
+ extractAttributes(application, assertingParty, *attr, attributes);
+ }
+}
+
void XMLExtractor::extractAttributes(
const Application& application, const RoleDescriptor* issuer, const XMLObject& xmlObject, vector<Attribute*>& attributes
) const
throw AttributeExtractionException("Unable to extract attributes, unknown object type.");
}
+ // Check for metadata.
+ if (XMLString::equals(xmlObject.getElementQName().getNamespaceURI(), samlconstants::SAML20MD_NS)) {
+ const EntityDescriptor* entity = dynamic_cast<const EntityDescriptor*>(&xmlObject);
+ if (!entity)
+ throw AttributeExtractionException("Unable to extract attributes, unknown metadata object type.");
+ auto_ptr_char assertingParty(issuer ? dynamic_cast<const EntityDescriptor*>(issuer->getParent())->getEntityID() : NULL);
+ const Extensions* ext = entity->getExtensions();
+ if (ext)
+ m_impl->extractAttributes(application, assertingParty.get(), *ext, attributes);
+ const EntitiesDescriptor* group = dynamic_cast<const EntitiesDescriptor*>(entity->getParent());
+ while (group) {
+ ext = group->getExtensions();
+ if (ext)
+ m_impl->extractAttributes(application, assertingParty.get(), *ext, attributes);
+ group = dynamic_cast<const EntitiesDescriptor*>(group->getParent());
+ }
+ return;
+ }
+
// Check for attributes.
if (XMLString::equals(xmlObject.getElementQName().getLocalPart(), saml1::Attribute::LOCAL_NAME)) {
auto_ptr_char assertingParty(issuer ? dynamic_cast<const EntityDescriptor*>(issuer->getParent())->getEntityID() : NULL);
const vector<const Assertion*>* tokens
) const
{
- // First we do the extraction of any pushed information.
+ const saml2md::EntityDescriptor* entity = dynamic_cast<const saml2md::EntityDescriptor*>(issuer->getParent());
+
+ // First we do the extraction of any pushed information, including from metadata.
vector<Attribute*> resolvedAttributes;
AttributeExtractor* extractor = application.getAttributeExtractor();
if (extractor) {
- m_log.debug("extracting pushed attributes...");
Locker extlocker(extractor);
+ if (entity) {
+ m_log.debug("extracting metadata-derived attributes...");
+ try {
+ extractor->extractAttributes(application, issuer, *entity, resolvedAttributes);
+ }
+ catch (exception& ex) {
+ m_log.error("caught exception extracting attributes: %s", ex.what());
+ }
+ }
+ m_log.debug("extracting pushed attributes...");
if (v1nameid) {
try {
extractor->extractAttributes(application, issuer, *v1nameid, resolvedAttributes);
try {
AttributeResolver* resolver = application.getAttributeResolver();
- if (!resolver && !resolvedAttributes.empty()) {
- m_log.info("no AttributeResolver available, skipping resolution");
- return new DummyContext(resolvedAttributes);
- }
-
- m_log.debug("resolving attributes...");
+ if (resolver) {
+ m_log.debug("resolving attributes...");
- Locker locker(resolver);
- auto_ptr<ResolutionContext> ctx(
- resolver->createResolutionContext(
- application,
- dynamic_cast<const saml2md::EntityDescriptor*>(issuer->getParent()),
- protocol,
- nameid,
- authncontext_class,
- authncontext_decl,
- tokens,
- &resolvedAttributes
- )
- );
- resolver->resolveAttributes(*ctx.get());
- return ctx.release();
+ Locker locker(resolver);
+ auto_ptr<ResolutionContext> ctx(
+ resolver->createResolutionContext(
+ application,
+ entity,
+ protocol,
+ nameid,
+ authncontext_class,
+ authncontext_decl,
+ tokens,
+ &resolvedAttributes
+ )
+ );
+ resolver->resolveAttributes(*ctx.get());
+ // Copy over any pushed attributes.
+ if (!resolvedAttributes.empty())
+ ctx->getResolvedAttributes().insert(ctx->getResolvedAttributes().end(), resolvedAttributes.begin(), resolvedAttributes.end());
+ return ctx.release();
+ }
}
catch (exception& ex) {
m_log.error("attribute resolution failed: %s", ex.what());