+++ /dev/null
-<AttributeAcceptancePolicy xmlns="urn:mace:shibboleth:1.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="urn:mace:shibboleth:1.0 @-PKGXMLDIR-@/shibboleth.xsd">
-
- <!--
- An AAP is a set of AttributeRule elements, each one
- referencing a specific attribute by URI. All attributes that
- should be visible to an application running at the target should
- be listed, or they will be filtered out.
-
- The Header and Alias attributes map an attribute to an HTTP header
- and to an htaccess rule name respectively. Without Header, the attribute
- will only be obtainable from the exported SAML assertion in raw XML.
-
- Scoped attributes can also be filtered on Scope via rules in the
- asserting identity provider's metadata.
-
- Finally, a note on naming. The attributes in this file are mostly drawn from
- the set documented here:
-
- http://middleware.internet2.edu/urn-mace/urn-mace-dir-attribute-def.html
-
- The actual naming convention most of them follow is NOT to be used for
- any subsequent attributes bound to SAML, and you are NOT free to just
- make up names using it, because the urn:mace:dir namespace tree is
- controlled. For help and advice on defining new attributes, refer to:
-
- https://authdev.it.ohio-state.edu/twiki/bin/view/Shibboleth/AttributeNaming
- -->
-
- <!-- First some useful eduPerson attributes that many sites might use. -->
-
- <AttributeRule Name="urn:mace:dir:attribute-def:eduPersonScopedAffiliation" Scoped="true" CaseSensitive="false" Header="Shib-EP-Affiliation" Alias="affiliation">
- <!-- Filtering rule to limit values to eduPerson-defined enumeration. -->
- <AnySite>
- <Value>MEMBER</Value>
- <Value>FACULTY</Value>
- <Value>STUDENT</Value>
- <Value>STAFF</Value>
- <Value>ALUM</Value>
- <Value>AFFILIATE</Value>
- <Value>EMPLOYEE</Value>
- </AnySite>
-
- <!-- Example of Scope rule to override site metadata. -->
- <SiteRule Name="urn:mace:inqueue:shibdev.edu">
- <Scope Accept="false">shibdev.edu</Scope>
- <Scope Type="regexp">^.+\.shibdev\.edu$</Scope>
- </SiteRule>
- </AttributeRule>
-
- <!--
- This attribute is provided mostly to ease testing because an IdP out of the box only
- sends the unscoped version. It has little use because it lacks the context needed to
- work in a multi-domain scenario and is a subset of the scoped version anyway.
- -->
- <AttributeRule Name="urn:mace:dir:attribute-def:eduPersonAffiliation" CaseSensitive="false" Header="Shib-EP-UnscopedAffiliation" Alias="unscoped-affiliation">
- <AnySite>
- <Value>MEMBER</Value>
- <Value>FACULTY</Value>
- <Value>STUDENT</Value>
- <Value>STAFF</Value>
- <Value>ALUM</Value>
- <Value>AFFILIATE</Value>
- <Value>EMPLOYEE</Value>
- </AnySite>
- </AttributeRule>
-
- <AttributeRule Name="urn:mace:dir:attribute-def:eduPersonPrincipalName" Scoped="true" Header="REMOTE_USER" Alias="user">
- <!-- Basic rule to pass through any value. -->
- <AnySite>
- <Value Type="regexp">^[^@]+$</Value>
- </AnySite>
- </AttributeRule>
-
- <AttributeRule Name="urn:mace:dir:attribute-def:eduPersonEntitlement" Header="Shib-EP-Entitlement" Alias="entitlement">
- <!-- Entitlements tend to be filtered per-site. -->
-
- <!--
- Optional site rule that applies to any site
- <AnySite>
- <Value>urn:mace:example.edu:exampleEntitlement</Value>
- </AnySite>
- -->
-
- <!-- Specific rules for an origin site, these are just development/sample sites. -->
- <SiteRule Name="urn:mace:inqueue:example.edu">
- <Value Type="regexp">^urn:mace:.+$</Value>
- </SiteRule>
- <SiteRule Name="urn:mace:inqueue:shibdev.edu">
- <Value Type="regexp">^urn:mace:.+$</Value>
- </SiteRule>
- </AttributeRule>
-
- <!-- A persistent id attribute that supports personalized anonymous access. -->
-
- <!-- First, the deprecated version: -->
- <AttributeRule Name="urn:mace:dir:attribute-def:eduPersonTargetedID" Scoped="true" Header="Shib-TargetedID" Alias="targeted_id">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- <!-- Second, the new version (note the OID-style name): -->
- <AttributeRule Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" Header="Shib-TargetedID" Alias="targeted_id">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- <!-- Some more eduPerson attributes, uncomment these to use them... -->
- <!--
-
- <AttributeRule Name="urn:mace:dir:attribute-def:eduPersonNickname">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- <AttributeRule Name="urn:mace:dir:attribute-def:eduPersonPrimaryAffiliation" CaseSensitive="false" Header="Shib-EP-PrimaryAffiliation">
- <AnySite>
- <Value>MEMBER</Value>
- <Value>FACULTY</Value>
- <Value>STUDENT</Value>
- <Value>STAFF</Value>
- <Value>ALUM</Value>
- <Value>AFFILIATE</Value>
- <Value>EMPLOYEE</Value>
- </AnySite>
- </AttributeRule>
-
- <AttributeRule Name="urn:mace:dir:attribute-def:eduPersonPrimaryOrgUnitDN" Header="Shib-EP-PrimaryOrgUnitDN">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- <AttributeRule Name="urn:mace:dir:attribute-def:eduPersonOrgUnitDN" Header="Shib-EP-OrgUnitDN">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- <AttributeRule Name="urn:mace:dir:attribute-def:eduPersonOrgDN" Header="Shib-EP-OrgDN">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- -->
-
-
- <!--Examples of common LDAP-based attributes, uncomment to use these... -->
- <!--
-
- <AttributeRule Name="urn:mace:dir:attribute-def:cn" Header="Shib-Person-commonName">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- <AttributeRule Name="urn:mace:dir:attribute-def:sn" Header="Shib-Person-surname">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- <AttributeRule Name="urn:mace:dir:attribute-def:mail" Header="Shib-InetOrgPerson-mail">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- <AttributeRule Name="urn:mace:dir:attribute-def:telephoneNumber" Header="Shib-Person-telephoneNumber">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- <AttributeRule Name="urn:mace:dir:attribute-def:title" Header="Shib-OrgPerson-title">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- <AttributeRule Name="urn:mace:dir:attribute-def:initials" Header="Shib-InetOrgPerson-initials">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- <AttributeRule Name="urn:mace:dir:attribute-def:description" Header="Shib-Person-description">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- <AttributeRule Name="urn:mace:dir:attribute-def:carLicense" Header="Shib-InetOrgPerson-carLicense">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- <AttributeRule Name="urn:mace:dir:attribute-def:departmentNumber" Header="Shib-InetOrgPerson-deptNum">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- <AttributeRule Name="urn:mace:dir:attribute-def:displayName" Header="Shib-InetOrgPerson-displayName">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- <AttributeRule Name="urn:mace:dir:attribute-def:employeeNumber" Header="Shib-InetOrgPerson-employeeNum">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- <AttributeRule Name="urn:mace:dir:attribute-def:employeeType" Header="Shib-InetOrgPerson-employeeType">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- <AttributeRule Name="urn:mace:dir:attribute-def:preferredLanguage" Header="Shib-InetOrgPerson-prefLang">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- <AttributeRule Name="urn:mace:dir:attribute-def:manager" Header="Shib-InetOrgPerson-manager">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- <AttributeRule Name="urn:mace:dir:attribute-def:roomNumber" Header="Shib-InetOrgPerson-roomNum">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- <AttributeRule Name="urn:mace:dir:attribute-def:seeAlso" Header="Shib-OrgPerson-seeAlso">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- <AttributeRule Name="urn:mace:dir:attribute-def:facsimileTelephoneNumber" Header="Shib-OrgPerson-fax">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- <AttributeRule Name="urn:mace:dir:attribute-def:street" Header="Shib-OrgPerson-street">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- <AttributeRule Name="urn:mace:dir:attribute-def:postOfficeBox" Header="Shib-OrgPerson-POBox">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- <AttributeRule Name="urn:mace:dir:attribute-def:postalCode" Header="Shib-OrgPerson-postalCode">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- <AttributeRule Name="urn:mace:dir:attribute-def:st" Header="Shib-OrgPerson-state">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- <AttributeRule Name="urn:mace:dir:attribute-def:givenName" Header="Shib-InetOrgPerson-givenName">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- <AttributeRule Name="urn:mace:dir:attribute-def:l" Header="Shib-OrgPerson-locality">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- <AttributeRule Name="urn:mace:dir:attribute-def:businessCategory" Header="Shib-InetOrgPerson-businessCat">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- <AttributeRule Name="urn:mace:dir:attribute-def:ou" Header="Shib-OrgPerson-orgUnit">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- <AttributeRule Name="urn:mace:dir:attribute-def:physicalDeliveryOfficeName" Header="Shib-OrgPerson-OfficeName">
- <AnySite>
- <AnyValue/>
- </AnySite>
- </AttributeRule>
-
- -->
-
-</AttributeAcceptancePolicy>
shibboleth.xml \
native.logger \
shibd.logger \
- AAP.xml \
+ resolver-simple.xml \
example-metadata.xml
# While BUILTCONFIGFILES are processed, these are not; so we should pull
shibboleth.xml: ${srcdir}/shibboleth.xml.in Makefile ${top_builddir}/config.status
$(MAKE) do-build-file FILE=$@
-AAP.xml: ${srcdir}/AAP.xml.in Makefile ${top_builddir}/config.status
+resolver-simple.xml: ${srcdir}/resolver-simple.xml.in Makefile ${top_builddir}/config.status
$(MAKE) do-build-file FILE=$@
example-metadata.xml: ${srcdir}/example-metadata.xml.in Makefile ${top_builddir}/config.status
shibd.logger \
native.logger \
shibboleth.xml \
- AAP.xml \
+ resolver-simple.xml \
example-metadata.xml
EXTRA_DIST = .cvsignore \
sessionError.html \
metadataError.html \
sslError.html \
- AAP.xml.in \
+ resolver-simple.xml.in \
example-metadata.xml.in \
sp-example.key \
sp-example.crt
--- /dev/null
+<ar:AttributeResolver xmlns:ar="urn:mace:shibboleth:2.0:resolver:simple"
+ xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver:simple @-PKGXMLDIR-@/shibboleth-2.0-simple-resolver.xsd"
+ allowQuery="true">
+
+ <!--
+ Built-in decoders that can extract SAML Attribute data.
+ Custom decoders can be configured here as well.
+ -->
+ <ar:AttributeDecoder id="Simple" type="Simple"/>
+ <ar:AttributeDecoder id="Scoped" type="Scoped"/>
+ <ar:AttributeDecoder id="NameID" type="NameID" formatter="$Name!!$NameQualifier!!$SPNameQualifier"/>
+
+ <!--
+ The simple resolver just enumerates SAML Attribute elements, each one
+ referencing a specific Attribute by its name on the wire, and its local
+ "friendly" ID. All Attributes that should be visible to an application
+ should be listed, or they will be ignored by the resolver.
+ -->
+
+ <!-- First some useful eduPerson attributes that many sites might use. -->
+
+ <saml:Attribute Name="urn:mace:dir:attribute-def:eduPersonPrincipalName" FriendlyName="REMOTE_USER" ar:decoderId="Scoped"/>
+ <saml:Attribute Name="urn:mace:dir:attribute-def:eduPersonScopedAffiliation" FriendlyName="affiliation" ar:decoderId="Scoped"/>
+ <saml:Attribute Name="urn:mace:dir:attribute-def:eduPersonAffiliation" FriendlyName="unscoped-affiliation" ar:decoderId="Simple"/>
+ <saml:Attribute Name="urn:mace:dir:attribute-def:eduPersonEntitlement" FriendlyName="entitlement" ar:decoderId="Simple"/>
+
+ <!-- A persistent id attribute that supports personalized anonymous access. -->
+
+ <!-- First, the deprecated version: -->
+ <saml:Attribute Name="urn:mace:dir:attribute-def:eduPersonTargetedID" FriendlyName="REMOTE_USER" ar:decoderId="Scoped"/>
+
+ <!-- Second, the new version (note the OID-style name): -->
+ <saml:Attribute Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" FriendlyName="REMOTE_USER" ar:decoderId="NameID"/>
+
+ <!-- Third, the SAML 2.0 NameID Format: -->
+ <saml:Attribute Name="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" FriendlyName="REMOTE_USER" ar:decoderId="NameID"/>
+
+ <!-- Some more eduPerson attributes, uncomment these to use them... -->
+ <!--
+ <saml:Attribute Name="urn:mace:dir:attribute-def:eduPersonNickname" FriendlyName="nickname" ar:decoderId="Simple"/>
+ <saml:Attribute Name="urn:mace:dir:attribute-def:eduPersonPrimaryAffiliation" FriendlyName="primary-affiliation" ar:decoderId="Simple"/>
+ <saml:Attribute Name="urn:mace:dir:attribute-def:eduPersonPrimaryOrgUnitDN" FriendlyName="primary-orgunit-dn" ar:decoderId="Simple"/>
+ <saml:Attribute Name="urn:mace:dir:attribute-def:eduPersonOrgUnitDN" FriendlyName="orgunit-dn" ar:decoderId="Simple"/>
+ <saml:Attribute Name="urn:mace:dir:attribute-def:eduPersonOrgDN" FriendlyName="org-dn" ar:decoderId="Simple"/>
+ -->
+
+ <!--Examples of LDAP-based attributes, uncomment to use these... -->
+ <!--
+ <saml:Attribute Name="urn:mace:dir:attribute-def:cn" FriendlyName="cn" ar:decoderId="Simple"/>
+ <saml:Attribute Name="urn:mace:dir:attribute-def:sn" FriendlyName="sn" ar:decoderId="Simple"/>
+ <saml:Attribute Name="urn:mace:dir:attribute-def:givenName" FriendlyName="givenName" ar:decoderId="Simple"/>
+ <saml:Attribute Name="urn:mace:dir:attribute-def:mail" FriendlyName="mail" ar:decoderId="Simple"/>
+ <saml:Attribute Name="urn:mace:dir:attribute-def:telephoneNumber" FriendlyName="telephoneNumber" ar:decoderId="Simple"/>
+ <saml:Attribute Name="urn:mace:dir:attribute-def:title" FriendlyName="title" ar:decoderId="Simple"/>
+ <saml:Attribute Name="urn:mace:dir:attribute-def:initials" FriendlyName="initials" ar:decoderId="Simple"/>
+ <saml:Attribute Name="urn:mace:dir:attribute-def:description" FriendlyName="description" ar:decoderId="Simple"/>
+ <saml:Attribute Name="urn:mace:dir:attribute-def:carLicense" FriendlyName="carLicense" ar:decoderId="Simple"/>
+ <saml:Attribute Name="urn:mace:dir:attribute-def:departmentNumber" FriendlyName="departmentNumber" ar:decoderId="Simple"/>
+ <saml:Attribute Name="urn:mace:dir:attribute-def:displayName" FriendlyName="displayName" ar:decoderId="Simple"/>
+ <saml:Attribute Name="urn:mace:dir:attribute-def:employeeNumber" FriendlyName="employeeNumber" ar:decoderId="Simple"/>
+ <saml:Attribute Name="urn:mace:dir:attribute-def:employeeType" FriendlyName="employeeType" ar:decoderId="Simple"/>
+ <saml:Attribute Name="urn:mace:dir:attribute-def:preferredLanguage" FriendlyName="preferredLanguage" ar:decoderId="Simple"/>
+ <saml:Attribute Name="urn:mace:dir:attribute-def:manager" FriendlyName="manager" ar:decoderId="Simple"/>
+ <saml:Attribute Name="urn:mace:dir:attribute-def:seeAlso" FriendlyName="seeAlso" ar:decoderId="Simple"/>
+ <saml:Attribute Name="urn:mace:dir:attribute-def:facsimileTelephoneNumber" FriendlyName="facsimileTelephoneNumber" ar:decoderId="Simple"/>
+ <saml:Attribute Name="urn:mace:dir:attribute-def:street" FriendlyName="street" ar:decoderId="Simple"/>
+ <saml:Attribute Name="urn:mace:dir:attribute-def:postOfficeBox" FriendlyName="postOfficeBox" ar:decoderId="Simple"/>
+ <saml:Attribute Name="urn:mace:dir:attribute-def:postalCode" FriendlyName="postalCode" ar:decoderId="Simple"/>
+ <saml:Attribute Name="urn:mace:dir:attribute-def:st" FriendlyName="st" ar:decoderId="Simple"/>
+ <saml:Attribute Name="urn:mace:dir:attribute-def:l" FriendlyName="l" ar:decoderId="Simple"/>
+ <saml:Attribute Name="urn:mace:dir:attribute-def:ou" FriendlyName="ou" ar:decoderId="Simple"/>
+ <saml:Attribute Name="urn:mace:dir:attribute-def:businessCategory" FriendlyName="businessCategory" ar:decoderId="Simple"/>
+ <saml:Attribute Name="urn:mace:dir:attribute-def:physicalDeliveryOfficeName" FriendlyName="physicalDeliveryOfficeName" ar:decoderId="Simple"/>
+ -->
+
+</ar::AttributeResolver>
<TrustEngine type="PKIX"/>
</TrustEngine>
+ <AttributeResolver type="Simple" path="@-PKGSYSCONFDIR-@/resolver-simple.xml"/>
</Applications>
<!-- Define all the private keys and certificates here that you reference from <CredentialUse>. -->
</element>
<complexType name="AttributeResolverType">
<sequence>
- <element ref="saml:Attribute" minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="resolver:AttributeDecoder" maxOccurs="unbounded"/>
+ <element ref="saml:Attribute" maxOccurs="unbounded"/>
</sequence>
<attribute name="allowQuery" type="boolean" default="true"/>
</complexType>
+ <element name="AttributeDecoder">
+ <annotation>
+ <documentation>Instantiates decoders for use by Attribute definitions.</documentation>
+ </annotation>
+ <complexType>
+ <sequence>
+ <any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="type" type="resolver:string" use="required"/>
+ <attribute name="id" type="ID" use="required"/>
+ <anyAttribute namespace="##any" processContents="lax"/>
+ </complexType>
+ </element>
+
<simpleType name="string">
<restriction base="string">
<minLength value="1"/>
</restriction>
</simpleType>
- <attribute name="decoderType" type="resolver:string"/>
+ <attribute name="decoderId" type="IDREF"/>
</schema>
<element ref="saml:Audience" minOccurs="0" maxOccurs="unbounded"/>
<element name="MetadataProvider" type="conf:PluggableType"/>
<element name="TrustEngine" type="conf:PluggableType"/>\r
+ <element name="AttributeResolver" type="conf:PluggableType"/>\r
<element ref="conf:Application" minOccurs="0" maxOccurs="unbounded"/>\r
</sequence>\r
<attribute name="id" type="conf:string" fixed="default"/>\r
<element ref="saml:Audience" minOccurs="0" maxOccurs="unbounded"/>\r
<element name="MetadataProvider" type="conf:PluggableType" minOccurs="0"/>\r
<element name="TrustEngine" type="conf:PluggableType" minOccurs="0"/>\r
+ <element name="AttributeResolver" type="conf:PluggableType" minOccurs="0"/>\r
</sequence>\r
<attribute name="id" type="conf:string" use="required"/>\r
<attribute name="providerId" type="anyURI"/>\r
(shar_checkonly ? (SPConfig::InProcess | SPConfig::RequestMapping) : SPConfig::Logging)\r
);\r
if (!shar_config)\r
- shar_config=getenv("SHIBCONFIG");\r
+ shar_config=getenv("SHIBSP_CONFIG");\r
if (!shar_schemadir)\r
- shar_schemadir=getenv("SHIBSCHEMAS");\r
+ shar_schemadir=getenv("SHIBSP_SCHEMAS");\r
if (!shar_schemadir)\r
shar_schemadir=SHIBSP_SCHEMAS;\r
if (!shar_config)\r
usage(argv[0]);\r
\r
if (!shar_config)\r
- shar_config=getenv("SHIBCONFIG");\r
+ shar_config=getenv("SHIBSP_CONFIG");\r
if (!shar_schemadir)\r
- shar_schemadir=getenv("SHIBSCHEMAS");\r
+ shar_schemadir=getenv("SHIBSP_SCHEMAS");\r
if (!shar_schemadir)\r
shar_schemadir=SHIBSP_SCHEMAS;\r
if (!shar_config)\r
namespace shibsp {
+ class SHIBSP_API AttributeResolver;
class SHIBSP_API Handler;
class SHIBSP_API ServiceProvider;
* @return a TrustEngine instance, or NULL
*/
virtual xmltooling::TrustEngine* getTrustEngine() const=0;
-
+
+ /**
+ * Returns an AttributeResolver for use with this Application.
+ *
+ * @return an AttributeResolver, or NULL
+ */
+ virtual AttributeResolver* getAttributeResolver() const=0;
+
/**
* Returns configuration properties governing security interactions with a peer entity.
*
/**
* Decodes an XMLObject into a resolved Attribute.
*
- * @param id ID of resolved attribute
- * @param xmlObject XMLObject to decode
+ * @param id ID of resolved attribute
+ * @param xmlObject XMLObject to decode
+ * @param assertingParty name of the party asserting the attribute
+ * @param relyingParty name of the party relying on the attribute
* @return a resolved Attribute
*/
- virtual Attribute* decode(const char* id, const xmltooling::XMLObject* xmlObject) const=0;
+ virtual Attribute* decode(
+ const char* id, const xmltooling::XMLObject* xmlObject, const char* assertingParty=NULL, const char* relyingParty=NULL
+ ) const=0;
};
/** Decodes SimpleAttributes */
NameIDAttributeDecoder(const DOMElement* e) : m_formatter(e ? e->getAttributeNS(NULL,formatter) : NULL) {}\r
~NameIDAttributeDecoder() {}\r
\r
- shibsp::Attribute* decode(const char* id, const XMLObject* xmlObject) const;\r
+ shibsp::Attribute* decode(\r
+ const char* id, const XMLObject* xmlObject, const char* assertingParty=NULL, const char* relyingParty=NULL\r
+ ) const;\r
\r
private:\r
- void extract(const NameID* n, vector<NameIDAttribute::Value>& dest) const;\r
- void extract(const NameIdentifier* n, vector<NameIDAttribute::Value>& dest) const;\r
+ void extract(\r
+ const NameIDType* n, vector<NameIDAttribute::Value>& dest, const char* assertingParty=NULL, const char* relyingParty=NULL\r
+ ) const;\r
+ void extract(\r
+ const NameIdentifier* n, vector<NameIDAttribute::Value>& dest, const char* assertingParty=NULL, const char* relyingParty=NULL\r
+ ) const;\r
auto_ptr_char m_formatter;\r
};\r
\r
}\r
};\r
\r
-shibsp::Attribute* NameIDAttributeDecoder::decode(const char* id, const XMLObject* xmlObject) const\r
+shibsp::Attribute* NameIDAttributeDecoder::decode(\r
+ const char* id, const XMLObject* xmlObject, const char* assertingParty, const char* relyingParty\r
+ ) const\r
{\r
auto_ptr<NameIDAttribute> nameid(\r
new NameIDAttribute(id, (m_formatter.get() && *m_formatter.get()) ? m_formatter.get() : DEFAULT_NAMEID_FORMATTER)\r
}\r
\r
for (; v!=stop; ++v) {\r
- const NameID* n2 = dynamic_cast<const NameID*>(*v);\r
+ const NameIDType* n2 = dynamic_cast<const NameIDType*>(*v);\r
if (n2)\r
extract(n2, dest);\r
else {\r
else if ((*v)->hasChildren()) {\r
const list<XMLObject*>& values = (*v)->getOrderedChildren();\r
for (list<XMLObject*>::const_iterator vv = values.begin(); vv!=values.end(); ++vv) {\r
- if (n2=dynamic_cast<const NameID*>(*vv))\r
+ if (n2=dynamic_cast<const NameIDType*>(*vv))\r
extract(n2, dest);\r
else if (n1=dynamic_cast<const NameIdentifier*>(*vv))\r
extract(n1, dest);\r
return dest.empty() ? NULL : nameid.release();\r
}\r
\r
- const NameID* saml2name = dynamic_cast<const NameID*>(xmlObject);\r
+ const NameIDType* saml2name = dynamic_cast<const NameIDType*>(xmlObject);\r
if (saml2name) {\r
if (log.isDebugEnabled()) {\r
auto_ptr_char f(saml2name->getFormat());\r
return dest.empty() ? NULL : nameid.release();\r
}\r
\r
-void NameIDAttributeDecoder::extract(const NameID* n, vector<NameIDAttribute::Value>& dest) const\r
+void NameIDAttributeDecoder::extract(\r
+ const NameIDType* n, vector<NameIDAttribute::Value>& dest, const char* assertingParty, const char* relyingParty\r
+ ) const\r
{\r
char* name = toUTF8(n->getName());\r
if (name && *name) {\r
val.m_Format = str;\r
delete[] str;\r
}\r
+ \r
str = toUTF8(n->getNameQualifier());\r
- if (str) {\r
+ if (str && *str)\r
val.m_NameQualifier = str;\r
- delete[] str;\r
- }\r
+ else if (assertingParty)\r
+ val.m_NameQualifier = assertingParty;\r
+ delete[] str;\r
+ \r
str = toUTF8(n->getSPNameQualifier());\r
- if (str) {\r
+ if (str && *str)\r
val.m_SPNameQualifier = str;\r
- delete[] str;\r
- }\r
+ else if (relyingParty)\r
+ val.m_SPNameQualifier = relyingParty;\r
+ delete[] str;\r
+ \r
str = toUTF8(n->getSPProvidedID());\r
if (str) {\r
val.m_SPProvidedID = str;\r
delete[] name;\r
}\r
\r
-void NameIDAttributeDecoder::extract(const NameIdentifier* n, vector<NameIDAttribute::Value>& dest) const\r
+void NameIDAttributeDecoder::extract(\r
+ const NameIdentifier* n, vector<NameIDAttribute::Value>& dest, const char* assertingParty, const char* relyingParty\r
+ ) const\r
{\r
char* name = toUTF8(n->getName());\r
if (name && *name) {\r
val.m_Format = str;\r
delete[] str;\r
}\r
+\r
str = toUTF8(n->getNameQualifier());\r
- if (str) {\r
+ if (str && *str)\r
val.m_NameQualifier = str;\r
- delete[] str;\r
- }\r
+ else if (assertingParty)\r
+ val.m_NameQualifier = assertingParty;\r
+ delete[] str;\r
+ \r
+ if (relyingParty)\r
+ val.m_SPNameQualifier = relyingParty;\r
}\r
delete[] name;\r
}\r
ScopedAttributeDecoder(const DOMElement* e) {}\r
~ScopedAttributeDecoder() {}\r
\r
- shibsp::Attribute* decode(const char* id, const XMLObject* xmlObject) const;\r
+ shibsp::Attribute* decode(\r
+ const char* id, const XMLObject* xmlObject, const char* assertingParty=NULL, const char* relyingParty=NULL\r
+ ) const;\r
};\r
\r
AttributeDecoder* SHIBSP_DLLLOCAL ScopedAttributeDecoderFactory(const DOMElement* const & e)\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
+shibsp::Attribute* ScopedAttributeDecoder::decode(\r
+ const char* id, const XMLObject* xmlObject, const char* assertingParty, const char* relyingParty\r
+ ) const\r
{\r
char* val;\r
char* scope;\r
SimpleAttributeDecoder(const DOMElement* e) {}\r
~SimpleAttributeDecoder() {}\r
\r
- shibsp::Attribute* decode(const char* id, const XMLObject* xmlObject) const;\r
+ shibsp::Attribute* decode(\r
+ const char* id, const XMLObject* xmlObject, const char* assertingParty=NULL, const char* relyingParty=NULL\r
+ ) const;\r
};\r
\r
AttributeDecoder* SHIBSP_DLLLOCAL SimpleAttributeDecoderFactory(const DOMElement* const & e)\r
}\r
};\r
\r
-shibsp::Attribute* SimpleAttributeDecoder::decode(const char* id, const XMLObject* xmlObject) const\r
+shibsp::Attribute* SimpleAttributeDecoder::decode(\r
+ const char* id, const XMLObject* xmlObject, const char* assertingParty, const char* relyingParty\r
+ ) const\r
{\r
char* val;\r
auto_ptr<SimpleAttribute> simple(new SimpleAttribute(id));\r
chLatin_r, chLatin_e, chLatin_s, chLatin_o, chLatin_l, chLatin_v, chLatin_e, chLatin_r, chColon,\r
chLatin_s, chLatin_i, chLatin_m, chLatin_p, chLatin_l, chLatin_e, chNull\r
};\r
+ static const XMLCh _AttributeDecoder[] = UNICODE_LITERAL_16(A,t,t,r,i,b,u,t,e,D,e,c,o,d,e,r);\r
static const XMLCh _AttributeResolver[] = UNICODE_LITERAL_17(A,t,t,r,i,b,u,t,e,R,e,s,o,l,v,e,r);\r
static const XMLCh allowQuery[] = UNICODE_LITERAL_10(a,l,l,o,w,Q,u,e,r,y);\r
- static const XMLCh decoderType[] = UNICODE_LITERAL_11(d,e,c,o,d,e,r,T,y,p,e);\r
+ static const XMLCh decoderId[] = UNICODE_LITERAL_9(d,e,c,o,d,e,r,I,d);\r
+ static const XMLCh _id[] = UNICODE_LITERAL_2(i,d);\r
+ static const XMLCh _type[] = UNICODE_LITERAL_4(t,y,p,e);\r
};\r
\r
SimpleResolverImpl::SimpleResolverImpl(const DOMElement* e) : m_document(NULL), m_allowQuery(true)\r
log.info("SAML attribute queries disabled");\r
m_allowQuery = false;\r
}\r
+\r
+ DOMElement* child = XMLHelper::getFirstChildElement(e, SIMPLE_NS, _AttributeDecoder);\r
+ while (child) {\r
+ auto_ptr_char id(child->getAttributeNS(NULL, _id));\r
+ auto_ptr_char type(child->getAttributeNS(NULL, _type));\r
+ try {\r
+ log.info("building AttributeDecoder (%s) of type %s", id.get(), type.get());\r
+ m_decoderMap[id.get()] = SPConfig::getConfig().AttributeDecoderManager.newPlugin(type.get(), child);\r
+ }\r
+ catch (exception& ex) {\r
+ log.error("error building AttributeDecoder (%s): %s", id.get(), ex.what());\r
+ }\r
+ child = XMLHelper::getNextSiblingElement(child, SIMPLE_NS, _AttributeDecoder);\r
+ }\r
\r
- e = XMLHelper::getFirstChildElement(e, samlconstants::SAML20_NS, opensaml::saml2::Attribute::LOCAL_NAME);\r
- while (e) {\r
+ child = XMLHelper::getFirstChildElement(e, samlconstants::SAML20_NS, opensaml::saml2::Attribute::LOCAL_NAME);\r
+ while (child) {\r
// Check for missing Name.\r
- const XMLCh* name = e->getAttributeNS(NULL, opensaml::saml2::Attribute::NAME_ATTRIB_NAME);\r
+ const XMLCh* name = child->getAttributeNS(NULL, opensaml::saml2::Attribute::NAME_ATTRIB_NAME);\r
if (!name || !*name) {\r
log.warn("skipping saml:Attribute declared with no Name");\r
- e = XMLHelper::getNextSiblingElement(e, samlconstants::SAML20_NS, opensaml::saml2::Attribute::LOCAL_NAME);\r
+ child = XMLHelper::getNextSiblingElement(child, samlconstants::SAML20_NS, opensaml::saml2::Attribute::LOCAL_NAME);\r
continue;\r
}\r
\r
- auto_ptr_char id(e->getAttributeNS(NULL, opensaml::saml2::Attribute::FRIENDLYNAME_ATTRIB_NAME));\r
- if (!id.get() || !*id.get()) {\r
- log.warn("skipping saml:Attribute declared with no FriendlyName");\r
- e = XMLHelper::getNextSiblingElement(e, samlconstants::SAML20_NS, opensaml::saml2::Attribute::LOCAL_NAME);\r
+ const AttributeDecoder* decoder=NULL;\r
+ auto_ptr_char id(child->getAttributeNS(NULL, opensaml::saml2::Attribute::FRIENDLYNAME_ATTRIB_NAME));\r
+ auto_ptr_char d(child->getAttributeNS(SIMPLE_NS, decoderId));\r
+ if (!id.get() || !*id.get() || !d.get() || !*d.get() || !(decoder=m_decoderMap[d.get()])) {\r
+ log.warn("skipping saml:Attribute declared with no FriendlyName or resolvable AttributeDecoder");\r
+ child = XMLHelper::getNextSiblingElement(child, samlconstants::SAML20_NS, opensaml::saml2::Attribute::LOCAL_NAME);\r
continue;\r
}\r
\r
- auto_ptr_char d(e->getAttributeNS(SIMPLE_NS, decoderType));\r
- const char* dtype = d.get();\r
- if (!dtype || !*dtype)\r
- dtype = SIMPLE_ATTRIBUTE_DECODER;\r
- AttributeDecoder*& decoder = m_decoderMap[dtype];\r
- if (!decoder) {\r
- try {\r
- decoder = SPConfig::getConfig().AttributeDecoderManager.newPlugin(dtype, NULL);\r
- }\r
- catch (exception& ex) {\r
- log.error("error building AttributeDecoder: %s", ex.what());\r
- e = XMLHelper::getNextSiblingElement(e, samlconstants::SAML20_NS, opensaml::saml2::Attribute::LOCAL_NAME);\r
- continue;\r
- }\r
- }\r
- \r
// Empty NameFormat implies the usual Shib URI naming defaults.\r
- const XMLCh* format = e->getAttributeNS(NULL, opensaml::saml2::Attribute::NAMEFORMAT_ATTRIB_NAME);\r
+ const XMLCh* format = child->getAttributeNS(NULL, opensaml::saml2::Attribute::NAMEFORMAT_ATTRIB_NAME);\r
if (!format || XMLString::equals(format, shibspconstants::SHIB1_ATTRIBUTE_NAMESPACE_URI) ||\r
XMLString::equals(format, opensaml::saml2::Attribute::URI_REFERENCE))\r
format = &chNull; // ignore default Format/Namespace values\r
#endif\r
if (decl.first) {\r
log.warn("skipping duplicate saml:Attribute declaration (same Name and NameFormat)");\r
- e = XMLHelper::getNextSiblingElement(e, samlconstants::SAML20_NS, opensaml::saml2::Attribute::LOCAL_NAME);\r
+ child = XMLHelper::getNextSiblingElement(child, samlconstants::SAML20_NS, opensaml::saml2::Attribute::LOCAL_NAME);\r
continue;\r
}\r
\r
auto_ptr_char n(name);\r
auto_ptr_char f(format);\r
#endif\r
- log.debug("creating declaration for (Name=%s) %s%s)", n.get(), *f.get() ? "(Format/Namespace=" : "", f.get());\r
+ log.debug("creating declaration for Attribute %s%s%s", n.get(), *f.get() ? ", Format/Namespace:" : "", f.get());\r
}\r
\r
decl.first = decoder;\r
decl.second = id.get();\r
\r
- e = XMLHelper::getNextSiblingElement(e, samlconstants::SAML20_NS, opensaml::saml2::Attribute::LOCAL_NAME);\r
+ child = XMLHelper::getNextSiblingElement(child, samlconstants::SAML20_NS, opensaml::saml2::Attribute::LOCAL_NAME);\r
}\r
}\r
\r
\r
vector<shibsp::Attribute*>& resolved = ctx.getResolvedAttributes();\r
\r
+ auto_ptr_char assertingParty(ctx.getEntityDescriptor() ? ctx.getEntityDescriptor()->getEntityID() : NULL);\r
+ const char* relyingParty = ctx.getApplication().getString("providerId").second;\r
+\r
#ifdef HAVE_GOOD_STL\r
map< pair<xstring,xstring>,pair<const AttributeDecoder*,string> >::const_iterator rule;\r
#else\r
auto_ptr_char temp(format);\r
if ((rule=m_attrMap.find(make_pair(temp.get(),string()))) != m_attrMap.end()) {\r
#endif\r
- if (aset.empty() || aset.count(rule->second.second))\r
- resolved.push_back(rule->second.first->decode(rule->second.second.c_str(), &ctx.getNameID()));\r
+ if (aset.empty() || aset.count(rule->second.second)) {\r
+ resolved.push_back(\r
+ rule->second.first->decode(\r
+ rule->second.second.c_str(), &ctx.getNameID(), assertingParty.get(), relyingParty\r
+ )\r
+ );\r
+ }\r
}\r
}\r
\r
auto_ptr_char temp2(format);\r
if ((rule=m_attrMap.find(make_pair(temp1.get(),temp2.get()))) != m_attrMap.end()) {\r
#endif\r
- if (aset.empty() || aset.count(rule->second.second))\r
- resolved.push_back(rule->second.first->decode(rule->second.second.c_str(), *a));\r
+ if (aset.empty() || aset.count(rule->second.second)) {\r
+ resolved.push_back(\r
+ rule->second.first->decode(rule->second.second.c_str(), *a, assertingParty.get(), relyingParty)\r
+ );\r
+ }\r
}\r
}\r
}\r
\r
vector<shibsp::Attribute*>& resolved = ctx.getResolvedAttributes();\r
\r
+ auto_ptr_char assertingParty(ctx.getEntityDescriptor() ? ctx.getEntityDescriptor()->getEntityID() : NULL);\r
+ const char* relyingParty = ctx.getApplication().getString("providerId").second;\r
+\r
#ifdef HAVE_GOOD_STL\r
map< pair<xstring,xstring>,pair<const AttributeDecoder*,string> >::const_iterator rule;\r
#else\r
auto_ptr_char temp(format);\r
if ((rule=m_attrMap.find(make_pair(temp.get(),string()))) != m_attrMap.end()) {\r
#endif\r
- if (aset.empty() || aset.count(rule->second.second))\r
- resolved.push_back(rule->second.first->decode(rule->second.second.c_str(), &ctx.getNameID()));\r
+ if (aset.empty() || aset.count(rule->second.second)) {\r
+ resolved.push_back(\r
+ rule->second.first->decode(\r
+ rule->second.second.c_str(), &ctx.getNameID(), assertingParty.get(), relyingParty\r
+ )\r
+ );\r
+ }\r
}\r
}\r
\r
auto_ptr_char temp2(format);\r
if ((rule=m_attrMap.find(make_pair(temp1.get(),temp2.get()))) != m_attrMap.end()) {\r
#endif\r
- if (aset.empty() || aset.count(rule->second.second))\r
- resolved.push_back(rule->second.first->decode(rule->second.second.c_str(), *a));\r
+ if (aset.empty() || aset.count(rule->second.second)) {\r
+ resolved.push_back(\r
+ rule->second.first->decode(rule->second.second.c_str(), *a, assertingParty.get(), relyingParty)\r
+ );\r
+ }\r
}\r
}\r
}\r
#include "SPConfig.h"\r
#include "SPRequest.h"\r
#include "TransactionLog.h"\r
-#include "attribute/Attribute.h"\r
+#include "attribute/resolver/AttributeResolver.h"\r
#include "remoting/ListenerService.h"\r
#include "security/PKIXTrustEngine.h"\r
#include "util/DOMPropertySet.h"\r
pair<bool,const XMLCh*> getXMLString(const char* name, const char* ns=NULL) const;\r
pair<bool,unsigned int> getUnsignedInt(const char* name, const char* ns=NULL) const;\r
pair<bool,int> getInt(const char* name, const char* ns=NULL) const;\r
- const PropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:target:config:1.0") const;\r
+ const PropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:sp:config:2.0") const;\r
\r
// Application\r
const ServiceProvider& getServiceProvider() const {return *m_sp;}\r
const char* getId() const {return getString("id").second;}\r
const char* getHash() const {return m_hash.c_str();}\r
- MetadataProvider* getMetadataProvider() const;\r
- TrustEngine* getTrustEngine() const;\r
+\r
+ MetadataProvider* getMetadataProvider() const {\r
+ return (!m_metadata && m_base) ? m_base->getMetadataProvider() : m_metadata;\r
+ }\r
+ TrustEngine* getTrustEngine() const {\r
+ return (!m_trust && m_base) ? m_base->getTrustEngine() : m_trust;\r
+ }\r
+ AttributeResolver* getAttributeResolver() const {\r
+ return (!m_attrResolver && m_base) ? m_base->getAttributeResolver() : m_attrResolver;\r
+ }\r
+\r
const PropertySet* getCredentialUse(const EntityDescriptor* provider) const;\r
\r
const Handler* getDefaultSessionInitiator() const;\r
const vector<const Handler*>& getAssertionConsumerServicesByBinding(const XMLCh* binding) const;\r
const Handler* getHandler(const char* path) const;\r
\r
- const vector<const XMLCh*>& getAudiences() const;\r
+ const vector<const XMLCh*>& getAudiences() const {\r
+ return (m_audiences.empty() && m_base) ? m_base->getAudiences() : m_audiences;\r
+ }\r
Validator* getTokenValidator(time_t ts=0, const opensaml::saml2md::RoleDescriptor* role=NULL) const {\r
return new TokenValidator(*this, ts, role);\r
}\r
\r
- void validator(const XMLObject* xmlObject) const;\r
-\r
// Provides filter to exclude special config elements.\r
short acceptNode(const DOMNode* node) const;\r
\r
string m_hash;\r
MetadataProvider* m_metadata;\r
TrustEngine* m_trust;\r
+ AttributeResolver* m_attrResolver;\r
vector<const XMLCh*> m_audiences;\r
\r
// manage handler objects\r
\r
static const XMLCh _Application[] = UNICODE_LITERAL_11(A,p,p,l,i,c,a,t,i,o,n);\r
static const XMLCh Applications[] = UNICODE_LITERAL_12(A,p,p,l,i,c,a,t,i,o,n,s);\r
+ static const XMLCh _AttributeResolver[] = UNICODE_LITERAL_17(A,t,t,r,i,b,u,t,e,R,e,s,o,l,v,e,r);\r
static const XMLCh Credentials[] = UNICODE_LITERAL_11(C,r,e,d,e,n,t,i,a,l,s);\r
static const XMLCh CredentialUse[] = UNICODE_LITERAL_13(C,r,e,d,e,n,t,i,a,l,U,s,e);\r
static const XMLCh fatal[] = UNICODE_LITERAL_5(f,a,t,a,l);\r
const ServiceProvider* sp,\r
const DOMElement* e,\r
const XMLApplication* base\r
- ) : m_sp(sp), m_base(base), m_metadata(NULL), m_trust(NULL),\r
+ ) : m_sp(sp), m_base(base), m_metadata(NULL), m_trust(NULL), m_attrResolver(NULL),\r
m_credDefault(NULL), m_sessionInitDefault(NULL), m_acsDefault(NULL)\r
{\r
#ifdef _DEBUG\r
// Always include our own providerId as an audience.\r
m_audiences.push_back(getXMLString("providerId").second);\r
\r
- if (conf.isEnabled(SPConfig::AttributeResolution)) {\r
- // TODO\r
- }\r
-\r
if (conf.isEnabled(SPConfig::Metadata)) {\r
child = XMLHelper::getFirstChildElement(e,_MetadataProvider);\r
if (child) {\r
m_trust = xmlConf.TrustEngineManager.newPlugin(type.get(),child);\r
}\r
catch (exception& ex) {\r
- log.crit("error building TrustEngine: %s",ex.what());\r
+ log.crit("error building TrustEngine: %s", ex.what());\r
}\r
}\r
}\r
- \r
+\r
+ if (conf.isEnabled(SPConfig::AttributeResolution)) {\r
+ child = XMLHelper::getFirstChildElement(e,_AttributeResolver);\r
+ if (child) {\r
+ auto_ptr_char type(child->getAttributeNS(NULL,_type));\r
+ log.info("building AttributeResolver of type %s...",type.get());\r
+ try {\r
+ m_attrResolver = conf.AttributeResolverManager.newPlugin(type.get(),child);\r
+ }\r
+ catch (exception& ex) {\r
+ log.crit("error building AttributeResolver: %s", ex.what());\r
+ }\r
+ }\r
+ }\r
+\r
// Finally, load credential mappings.\r
child = XMLHelper::getFirstChildElement(e,CredentialUse);\r
if (child) {\r
for_each(m_credMap.begin(),m_credMap.end(),cleanup_pair<const XMLCh*,PropertySet>());\r
#endif\r
\r
+ delete m_attrResolver;\r
delete m_trust;\r
delete m_metadata;\r
}\r
XMLString::equals(name,CredentialUse) ||\r
XMLString::equals(name,RelyingParty) ||\r
XMLString::equals(name,_MetadataProvider) ||\r
- XMLString::equals(name,_TrustEngine))\r
+ XMLString::equals(name,_TrustEngine) ||\r
+ XMLString::equals(name,_AttributeResolver))\r
return FILTER_REJECT;\r
\r
return FILTER_ACCEPT;\r
return m_base->getPropertySet(name,ns);\r
}\r
\r
-MetadataProvider* XMLApplication::getMetadataProvider() const\r
-{\r
- return (!m_metadata && m_base) ? m_base->getMetadataProvider() : m_metadata;\r
-}\r
-\r
-TrustEngine* XMLApplication::getTrustEngine() const\r
-{\r
- return (!m_trust && m_base) ? m_base->getTrustEngine() : m_trust;\r
-}\r
-\r
-const vector<const XMLCh*>& XMLApplication::getAudiences() const\r
-{\r
- return (m_audiences.empty() && m_base) ? m_base->getAudiences() : m_audiences;\r
-}\r
-\r
const PropertySet* XMLApplication::getCredentialUse(const EntityDescriptor* provider) const\r
{\r
if (!m_credDefault && m_base)\r