[cpp-sp] branch master updated: SSPCPP-892

Scott Cantor cantor.2 at osu.edu
Wed Mar 18 12:34:17 EDT 2020


This is an automated email from the git hooks/post-receive script.

scantor pushed a commit to branch master
in repository cpp-sp.

View the commit online:
http://git.shibboleth.net/view/?p=cpp-sp.git;a=commit;h=9bb8b7ac9c5476a360823359e86928e39a5e3a49

The following commit(s) were added to refs/heads/master by this push:
       new  9bb8b7a   SSPCPP-892
9bb8b7a is described below

commit 9bb8b7ac9c5476a360823359e86928e39a5e3a49
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Wed Mar 18 12:33:25 2020 -0400

    SSPCPP-892
    
    https://issues.shibboleth.net/jira/browse/SSPCPP-892
    
    Cleanup and schema alignment.
---
 configs/attribute-policy.xml                       |  99 ++--
 schemas/shibboleth-2.0-afp.xsd                     | 653 ++++++++++++++++++++-
 shibsp/attribute/filtering/MatchFunctor.h          |   9 -
 .../impl/AttributeIssuerInEntityGroupFunctor.cpp   |  33 +-
 .../filtering/impl/AttributeIssuerRegexFunctor.cpp |  31 +-
 .../impl/AttributeIssuerStringFunctor.cpp          |  23 +-
 .../AttributeRequesterInEntityGroupFunctor.cpp     |  31 +-
 .../impl/AttributeRequesterRegexFunctor.cpp        |  31 +-
 .../impl/AttributeRequesterStringFunctor.cpp       |  23 +-
 .../filtering/impl/AttributeScopeRegexFunctor.cpp  |  29 +-
 .../filtering/impl/AttributeScopeStringFunctor.cpp |  22 +-
 .../filtering/impl/AttributeValueRegexFunctor.cpp  |  29 +-
 .../filtering/impl/AttributeValueStringFunctor.cpp |  18 +-
 .../impl/AuthenticationMethodRegexFunctor.cpp      |  31 +-
 .../impl/AuthenticationMethodStringFunctor.cpp     |  18 +-
 shibsp/attribute/filtering/impl/MatchFunctor.cpp   | 149 ++++-
 .../impl/RegistrationAuthorityFunctor.cpp          |   2 +-
 17 files changed, 1073 insertions(+), 158 deletions(-)

diff --git a/configs/attribute-policy.xml b/configs/attribute-policy.xml
index 6e97209..e701471 100644
--- a/configs/attribute-policy.xml
+++ b/configs/attribute-policy.xml
@@ -1,80 +1,77 @@
-<afp:AttributeFilterPolicyGroup
-    xmlns="urn:mace:shibboleth:2.0:afp:mf:basic"
-    xmlns:saml="urn:mace:shibboleth:2.0:afp:mf:saml"
-    xmlns:basic="urn:mace:shibboleth:2.0:afp:mf:basic"
-    xmlns:afp="urn:mace:shibboleth:2.0:afp"
+<AttributeFilterPolicyGroup
+    xmlns="urn:mace:shibboleth:2.0:afp"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 
     <!-- Shared rule for affiliation values. -->
-    <afp:PermitValueRule id="eduPersonAffiliationValues" xsi:type="OR">
-        <Rule xsi:type="AttributeValueString" value="faculty"/>
-        <Rule xsi:type="AttributeValueString" value="student"/>
-        <Rule xsi:type="AttributeValueString" value="staff"/>
-        <Rule xsi:type="AttributeValueString" value="alum"/>
-        <Rule xsi:type="AttributeValueString" value="member"/>
-        <Rule xsi:type="AttributeValueString" value="affiliate"/>
-        <Rule xsi:type="AttributeValueString" value="employee"/>
-        <Rule xsi:type="AttributeValueString" value="library-walk-in"/>
-    </afp:PermitValueRule>
+    <PermitValueRule id="eduPersonAffiliationValues" xsi:type="OR">
+        <Rule xsi:type="Value" value="faculty"/>
+        <Rule xsi:type="Value" value="student"/>
+        <Rule xsi:type="Value" value="staff"/>
+        <Rule xsi:type="Value" value="alum"/>
+        <Rule xsi:type="Value" value="member"/>
+        <Rule xsi:type="Value" value="affiliate"/>
+        <Rule xsi:type="Value" value="employee"/>
+        <Rule xsi:type="Value" value="library-walk-in"/>
+    </PermitValueRule>
     
     <!--
     Shared rule for all "scoped" attributes, but you'll have to manually apply it inside
     an AttributeRule for each attribute you want to check.
     -->
-    <afp:PermitValueRule id="ScopingRules" xsi:type="AND">
+    <PermitValueRule id="ScopingRules" xsi:type="AND">
         <Rule xsi:type="NOT">
-            <Rule xsi:type="AttributeValueRegex" regex="@"/>
+            <Rule xsi:type="ValueRegex" regex="@"/>
         </Rule>
         <Rule xsi:type="saml:AttributeScopeMatchesShibMDScope"/>
-    </afp:PermitValueRule>
+    </PermitValueRule>
 
-    <afp:AttributeFilterPolicy>
+    <AttributeFilterPolicy>
         <!-- This policy is in effect in all cases. -->
-        <afp:PolicyRequirementRule xsi:type="ANY"/>
+        <PolicyRequirementRule xsi:type="ANY"/>
 
         <!-- Filter out undefined affiliations and ensure only one primary. -->
-        <afp:AttributeRule attributeID="affiliation">
-            <afp:PermitValueRule xsi:type="AND">
+        <AttributeRule attributeID="affiliation">
+            <PermitValueRule xsi:type="AND">
                 <RuleReference ref="eduPersonAffiliationValues"/>
                 <RuleReference ref="ScopingRules"/>
-            </afp:PermitValueRule>
-        </afp:AttributeRule>
-        <afp:AttributeRule attributeID="unscoped-affiliation">
-            <afp:PermitValueRuleReference ref="eduPersonAffiliationValues"/>
-        </afp:AttributeRule>
-        <afp:AttributeRule attributeID="primary-affiliation">
-            <afp:PermitValueRuleReference ref="eduPersonAffiliationValues"/>
-        </afp:AttributeRule>
+            </PermitValueRule>
+        </AttributeRule>
+        <AttributeRule attributeID="unscoped-affiliation">
+            <PermitValueRuleReference ref="eduPersonAffiliationValues"/>
+        </AttributeRule>
+        <AttributeRule attributeID="primary-affiliation">
+            <PermitValueRuleReference ref="eduPersonAffiliationValues"/>
+        </AttributeRule>
 
-        <afp:AttributeRule attributeID="subject-id">
-            <afp:PermitValueRuleReference ref="ScopingRules"/>
-        </afp:AttributeRule>
+        <AttributeRule attributeID="subject-id">
+            <PermitValueRuleReference ref="ScopingRules"/>
+        </AttributeRule>
 
-        <afp:AttributeRule attributeID="pairwise-id">
-            <afp:PermitValueRuleReference ref="ScopingRules"/>
-        </afp:AttributeRule>
+        <AttributeRule attributeID="pairwise-id">
+            <PermitValueRuleReference ref="ScopingRules"/>
+        </AttributeRule>
         
-        <afp:AttributeRule attributeID="eppn">
-            <afp:PermitValueRuleReference ref="ScopingRules"/>
-        </afp:AttributeRule>
+        <AttributeRule attributeID="eppn">
+            <PermitValueRuleReference ref="ScopingRules"/>
+        </AttributeRule>
 
-        <afp:AttributeRule attributeID="targeted-id">
-            <afp:PermitValueRuleReference ref="ScopingRules"/>
-        </afp:AttributeRule>
+        <AttributeRule attributeID="targeted-id">
+            <PermitValueRuleReference ref="ScopingRules"/>
+        </AttributeRule>
 
         <!-- Require NameQualifier/SPNameQualifier match IdP and SP entityID respectively. -->
-        <afp:AttributeRule attributeID="persistent-id">
-            <afp:PermitValueRule xsi:type="saml:NameIDQualifierString"/>
-        </afp:AttributeRule>
+        <AttributeRule attributeID="persistent-id">
+            <PermitValueRule xsi:type="saml:NameIDQualifierString"/>
+        </AttributeRule>
         
         <!-- Enforce that the values of schacHomeOrganization are a valid Scope. -->
-        <afp:AttributeRule attributeID="schacHomeOrganization">
-            <afp:PermitValueRule xsi:type="saml:AttributeValueMatchesShibMDScope" />
-        </afp:AttributeRule>
+        <AttributeRule attributeID="schacHomeOrganization">
+            <PermitValueRule xsi:type="saml:AttributeValueMatchesShibMDScope" />
+        </AttributeRule>
 
         <!-- Catch-all that passes everything else through unmolested. -->
-        <afp:AttributeRule attributeID="*" permitAny="true"/>
+        <AttributeRule attributeID="*" permitAny="true"/>
         
-    </afp:AttributeFilterPolicy>
+    </AttributeFilterPolicy>
 
-</afp:AttributeFilterPolicyGroup>
+</AttributeFilterPolicyGroup>
diff --git a/schemas/shibboleth-2.0-afp.xsd b/schemas/shibboleth-2.0-afp.xsd
index ca54a7b..6f20a60 100644
--- a/schemas/shibboleth-2.0-afp.xsd
+++ b/schemas/shibboleth-2.0-afp.xsd
@@ -3,7 +3,7 @@
         xmlns:afp="urn:mace:shibboleth:2.0:afp"
         xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
         targetNamespace="urn:mace:shibboleth:2.0:afp"
-        version="2.6.0"
+        version="3.1.0"
         elementFormDefault="qualified">
 
     <import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd"/>
@@ -152,12 +152,12 @@
                         </element>
                     </choice>
                 </choice>
-                <attribute name="attributeID" type="string" use="required">
+                <attribute name="attributeID" type="afp:string" use="required">
                     <annotation>
                         <documentation>The ID of the attribute to which this rule applies.</documentation>
                     </annotation>
                 </attribute>
-                <attribute name="permitAny" type="string">
+                <attribute name="permitAny" type="boolean">
                     <annotation>
                         <documentation>If present, and true injects an implicit permit value rule of type ANY</documentation>
                     </annotation>
@@ -192,7 +192,7 @@
     </complexType>
 
     <complexType name="IdentityType">
-        <attribute name="id" type="string">
+        <attribute name="id" type="afp:string">
             <annotation>
                 <documentation>An ID, unique within the policy and component type.</documentation>
             </annotation>
@@ -200,11 +200,654 @@
     </complexType>
 
     <complexType name="ReferenceType">
-        <attribute name="ref" type="string">
+        <attribute name="ref" type="afp:string">
             <annotation>
                 <documentation>Used to reference a globally defined policy component.</documentation>
             </annotation>
         </attribute>
     </complexType>
 
+    <!-- Blanket Match Function -->
+    <complexType name="ANY">
+        <annotation>
+            <documentation>A match function that evaluates to true.</documentation>
+        </annotation>
+        <complexContent>
+            <extension base="afp:MatchFunctorType"/>
+        </complexContent>
+    </complexType>
+
+    <!--  Boolean Match Functions -->
+    <complexType name="AND">
+        <annotation>
+            <documentation>
+                A match function that performs a logical AND on the results of all contained matching functions.
+            </documentation>
+        </annotation>
+        <complexContent>
+            <extension base="afp:MatchFunctorType">
+                <choice maxOccurs="unbounded">
+                    <element name="Rule" type="afp:MatchFunctorType">
+                        <annotation>
+                            <documentation>
+                                The set of match function rules to be ANDed.
+                            </documentation>
+                        </annotation>
+                    </element>
+                    <element name="RuleReference" type="afp:ReferenceType">
+                        <annotation>
+                            <documentation>
+                                The set of match function rules to be ANDed.
+                            </documentation>
+                        </annotation>
+                    </element>
+                </choice>
+            </extension>
+        </complexContent>
+    </complexType>
+
+    <complexType name="OR">
+        <annotation>
+            <documentation>
+                A match function that performs a logical OR on the results of all contained matching functions.
+            </documentation>
+        </annotation>
+        <complexContent>
+            <extension base="afp:MatchFunctorType">
+                <choice maxOccurs="unbounded">
+                    <element name="Rule" type="afp:MatchFunctorType">
+                        <annotation>
+                            <documentation>
+                                The set of match function rules to be ORed.
+                            </documentation>
+                        </annotation>
+                    </element>
+                    <element name="RuleReference" type="afp:ReferenceType">
+                        <annotation>
+                            <documentation>
+                                The set of match function rules to be ORed.
+                            </documentation>
+                        </annotation>
+                    </element>
+                </choice>
+            </extension>
+        </complexContent>
+    </complexType>
+
+    <complexType name="NOT">
+        <annotation>
+            <documentation>
+                A match function that performs a logical NOT on the result of the contained matching function.
+            </documentation>
+        </annotation>
+        <complexContent>
+            <extension base="afp:MatchFunctorType">
+                <choice>
+                    <element name="Rule" type="afp:MatchFunctorType">
+                        <annotation>
+                            <documentation>
+                                The set of match function rules to be negated.
+                            </documentation>
+                        </annotation>
+                    </element>
+                    <element name="RuleReference" type="afp:ReferenceType">
+                        <annotation>
+                            <documentation>
+                                The set of match function rules to be negated.
+                            </documentation>
+                        </annotation>
+                    </element>
+                </choice>
+            </extension>
+        </complexContent>
+    </complexType>
+
+    <!--  Literal String Match Functions -->
+    <complexType name="Requester">
+        <annotation>
+            <documentation>
+                A match function that matches the attribute requester against the specified value.
+            </documentation>
+        </annotation>
+        <complexContent>
+            <extension base="afp:StringMatchType"/>
+        </complexContent>
+    </complexType>
+
+    <complexType name="Issuer">
+        <annotation>
+            <documentation>
+                A match function that matches the attribute issuer against the specified value.
+            </documentation>
+        </annotation>
+        <complexContent>
+            <extension base="afp:StringMatchType"/>
+        </complexContent>
+    </complexType>
+
+    <complexType name="AuthenticationMethod">
+        <annotation>
+            <documentation>
+                A match function that matches the authentication method against the specified value.
+            </documentation>
+        </annotation>
+        <complexContent>
+            <extension base="afp:StringMatchType" />
+        </complexContent>
+    </complexType>
+
+    <complexType name="Value">
+        <annotation>
+            <documentation>
+                A match function that matches the value of an attribute against the specified value. This match
+                evaluates to true if the attribute contains the specified value.
+            </documentation>
+        </annotation>
+        <complexContent>
+            <extension base="afp:TargetedStringMatchType"/>
+        </complexContent>
+    </complexType>
+
+    <complexType name="Scope">
+        <annotation>
+            <documentation>
+                A match function that matches the attribute scope against the specified value.
+            </documentation>
+        </annotation>
+        <complexContent>
+            <extension base="afp:TargetedStringMatchType"/>
+        </complexContent>
+    </complexType>
+
+    <complexType name="TargetedStringMatchType" abstract="true">
+        <complexContent>
+            <extension base="afp:StringMatchType">
+                <attribute name="attributeID" type="afp:string">
+                    <annotation>
+                        <documentation>
+                            The ID of the attribute whose value should be matched. If no attribute ID is specified the
+                            ID of the containing attribute rule is assumed.
+                        </documentation>
+                    </annotation>
+                </attribute>
+            </extension>
+        </complexContent>
+    </complexType>
+
+    <complexType name="StringMatchType" abstract="true">
+        <complexContent>
+            <extension base="afp:MatchFunctorType">
+                <attribute name="value" type="afp:string" use="required">
+                    <annotation>
+                        <documentation>The string value to match.</documentation>
+                    </annotation>
+                </attribute>
+                <attribute name="caseSensitive" type="boolean">
+                    <annotation>
+                        <documentation>
+                            A boolean flag indicating whether the match evaluation should be case sensitive.
+                        </documentation>
+                    </annotation>
+                </attribute>
+            </extension>
+        </complexContent>
+    </complexType>
+
+    <!--  Regular Expression Match Functions -->
+    <complexType name="RequesterRegex">
+        <annotation>
+            <documentation>
+                A match function that matches the attribute requester against the specified regular expression.
+            </documentation>
+        </annotation>
+        <complexContent>
+            <extension base="afp:RegexMatchType"/>
+        </complexContent>
+    </complexType>
+
+    <complexType name="IssuerRegex">
+        <annotation>
+            <documentation>
+                A match function that matches the attribute issuer against the specified regular expression.
+            </documentation>
+        </annotation>
+        <complexContent>
+            <extension base="afp:RegexMatchType"/>
+        </complexContent>
+    </complexType>
+
+    <complexType name="AuthenticationMethodRegex">
+        <annotation>
+            <documentation>
+                A match function that matches the authentication method against the specified regular expression.
+            </documentation>
+        </annotation>
+        <complexContent>
+            <extension base="afp:RegexMatchType" />
+        </complexContent>
+    </complexType>
+
+    <complexType name="ValueRegex">
+        <annotation>
+            <documentation>
+                A match function that matches an attribute value against the specified regular expression. This function
+                evaluates to true if any value matches the given expression.
+            </documentation>
+        </annotation>
+        <complexContent>
+            <extension base="afp:TargetedRegexMatchType"/>
+        </complexContent>
+    </complexType>
+
+    <complexType name="ScopeRegex">
+        <annotation>
+            <documentation>
+                A match function that matches the attribute scope against the specified regular expression.
+            </documentation>
+        </annotation>
+        <complexContent>
+            <extension base="afp:TargetedRegexMatchType"/>
+        </complexContent>
+    </complexType>
+
+    <complexType name="TargetedRegexMatchType" abstract="true">
+        <complexContent>
+            <extension base="afp:RegexMatchType">
+                <attribute name="attributeID" type="afp:string">
+                    <annotation>
+                        <documentation>
+                            The ID of the attribute whose value should be matched. If no attribute ID is specified the
+                            ID of the containing attribute rule is assumed.
+                        </documentation>
+                    </annotation>
+                </attribute>
+            </extension>
+        </complexContent>
+    </complexType>
+
+    <complexType name="RegexMatchType" abstract="true">
+        <complexContent>
+            <extension base="afp:MatchFunctorType">
+                <attribute name="regex" type="afp:string" use="required">
+                    <annotation>
+                        <documentation>The regular expression values are matched against.</documentation>
+                    </annotation>
+                </attribute>
+                <attribute name="caseSensitive" type="boolean">
+                    <annotation>
+                        <documentation>Whether the comparison is case sensitive, default TRUE</documentation>
+                    </annotation>
+                </attribute>     
+                <attribute name="options" type="afp:string">
+                    <annotation>
+                        <documentation>The regular expression options to apply.</documentation>
+                    </annotation>
+                </attribute>
+            </extension>
+        </complexContent>
+    </complexType>
+
+    <!-- Misc. Functions -->
+
+    <complexType name="NumberOfAttributeValues">
+        <annotation>
+            <documentation>
+                A match function that evaluates to true if the given attribute has as a number of values that falls
+                between the minimum and maximum. This method may be used as a sanity check to ensure that an unexpected
+                number of values did not come from the attribute resolver and be released.
+            </documentation>
+        </annotation>
+        <complexContent>
+            <extension base="afp:MatchFunctorType">
+                <attribute name="attributeID" type="afp:string" use="required">
+                    <annotation>
+                        <documentation>The ID of the attribute whose value should be matched.</documentation>
+                    </annotation>
+                </attribute>
+                <attribute name="minimum" type="nonNegativeInteger">
+                    <annotation>
+                        <documentation>Minimum number of values an attribute may have.</documentation>
+                    </annotation>
+                </attribute>
+                <attribute name="maximum" type="positiveInteger">
+                    <annotation>
+                        <documentation>Maximum number of values an attribute may have.</documentation>
+                    </annotation>
+                </attribute>
+            </extension>
+        </complexContent>
+    </complexType>
+
+    <!-- SAML-specific. -->
+
+    <complexType name="EntityAttributeExactMatch">
+        <annotation>
+            <documentation>
+                A match function that checks if the attribute requester's metadata
+                contains an entity attribute with the specified value.
+            </documentation>
+        </annotation>
+        <complexContent>
+            <extension base="afp:EntityAttributeExactMatchType"/>
+        </complexContent>
+    </complexType>
+
+    <complexType name="IssuerEntityAttributeExactMatch">
+        <annotation>
+            <documentation>
+                A match function that checks if the attribute issuer's metadata
+                contains an entity attribute with the specified value.
+            </documentation>
+        </annotation>
+        <complexContent>
+            <extension base="afp:EntityAttributeExactMatchType"/>
+        </complexContent>
+    </complexType>
+
+    <complexType name="EntityAttributeExactMatchType" abstract="true">
+        <complexContent>
+            <extension base="afp:MatchFunctorType">
+                <attribute name="attributeName" type="afp:string" use="required">
+                    <annotation>
+                        <documentation>The name of the entity attribute to match.</documentation>
+                    </annotation>
+                </attribute>
+                <attribute name="attributeValue" type="afp:string" use="required">
+                    <annotation>
+                        <documentation>The value of the entity attribute to match.</documentation>
+                    </annotation>
+                </attribute>
+                <attribute name="attributeNameFormat" type="afp:string">
+                    <annotation>
+                        <documentation>The NameFormat of the entity attribute to match.</documentation>
+                    </annotation>
+                </attribute>
+            </extension>
+        </complexContent>
+    </complexType>
+
+    <complexType name="EntityAttributeRegexMatch">
+        <annotation>
+            <documentation>
+                A match function that checks if the attribute requester's metadata
+                contains an entity attribute with a value that matches the given regular expression.
+            </documentation>
+        </annotation>
+        <complexContent>
+            <extension base="afp:EntityAttributeRegexMatchType"/>
+        </complexContent>
+    </complexType>
+
+    <complexType name="IssuerEntityAttributeRegexMatch">
+        <annotation>
+            <documentation>
+                A match function that checks if the attribute issuer's metadata
+                contains an entity attribute with a value that matches the given regular expression.
+            </documentation>
+        </annotation>
+        <complexContent>
+            <extension base="afp:EntityAttributeRegexMatchType"/>
+        </complexContent>
+    </complexType>
+
+    <complexType name="EntityAttributeRegexMatchType" abstract="true">
+        <complexContent>
+            <extension base="afp:MatchFunctorType">
+                <attribute name="attributeName" type="afp:string" use="required">
+                    <annotation>
+                        <documentation>The name of the entity attribute to match.</documentation>
+                    </annotation>
+                </attribute>
+                <attribute name="attributeValueRegex" type="afp:string" use="required">
+                    <annotation>
+                        <documentation>The regular expression that must match the value of the entity attribute to
+                            match.</documentation>
+                    </annotation>
+                </attribute>
+                <attribute name="attributeNameFormat" type="afp:string">
+                    <annotation>
+                        <documentation>The name format of the entity attribute to match.</documentation>
+                    </annotation>
+                </attribute>
+            </extension>
+        </complexContent>
+    </complexType>
+
+    <!-- TODO: implement NameID functions or remove -->
+
+    <complexType name="NameIDFormatExactMatch">
+        <annotation>
+            <documentation>
+                A match function that evaluates to true if the attribute requester supports a specified
+                NameID format.
+            </documentation>
+        </annotation>
+        <complexContent>
+            <extension base="afp:NameIDFormatExactMatchType"/>
+        </complexContent>
+    </complexType>
+
+    <complexType name="IssuerNameIDFormatExactMatch">
+        <annotation>
+            <documentation>
+                A match function that evaluates to true if the attribute issuer supports a specified
+                NameID format.
+            </documentation>
+        </annotation>
+        <complexContent>
+            <extension base="afp:NameIDFormatExactMatchType"/>
+        </complexContent>
+    </complexType>
+
+    <complexType name="NameIDFormatExactMatchType" abstract="true">
+        <complexContent>
+            <extension base="afp:MatchFunctorType">
+                <attribute name="nameIdFormat" type="afp:string" use="required">
+                    <annotation>
+                        <documentation>The NameID format that needs to be supported by the entity.</documentation>
+                    </annotation>
+                </attribute>
+            </extension>
+        </complexContent>
+    </complexType>
+
+    <complexType name="InEntityGroup">
+        <annotation>
+            <documentation>
+                A match function that evaluates to true if the attribute requester is found in metadata and
+                is a member of the given entity group.
+            </documentation>
+        </annotation>
+        <complexContent>
+            <extension base="afp:EntityGroupMatchType"/>
+        </complexContent>
+    </complexType>
+
+    <complexType name="IssuerInEntityGroup">
+        <annotation>
+            <documentation>
+                A match function that evaluates to true if the attribute issuer is found in metadata and
+                is a member of the given entity group.
+            </documentation>
+        </annotation>
+        <complexContent>
+            <extension base="afp:EntityGroupMatchType"/>
+        </complexContent>
+    </complexType>
+
+    <complexType name="EntityGroupMatchType" abstract="true">
+        <complexContent>
+            <extension base="afp:MatchFunctorType">
+                <attribute name="groupID" type="afp:string" use="required">
+                    <annotation>
+                        <documentation>The entity group ID that an entity must be in.</documentation>
+                    </annotation>
+                </attribute>
+                <attribute name="checkAffiliations" type="boolean">
+                    <annotation>
+                        <documentation>
+                            Whether to check for membership in metadata-based AffiliationDescriptors.
+                            
+                            Defaults to false.
+                        </documentation>
+                    </annotation>
+                </attribute>
+            </extension>
+        </complexContent>
+    </complexType>
+
+    <complexType name="RegistrationAuthority">
+        <annotation>
+            <documentation>
+                A match function that matches the SP (requester) MDRPI against a list of potential values.
+            </documentation>
+        </annotation>
+        <complexContent>
+            <extension base="afp:RegistrationAuthorityMatchType" />
+        </complexContent>
+    </complexType>
+        
+    <complexType name="IssuerRegistrationAuthority">
+        <annotation>
+            <documentation>
+                A match function that matches the attribute issuer's MDRPI content against a list of potential values.
+            </documentation>
+        </annotation>
+        <complexContent>
+            <extension base="afp:RegistrationAuthorityMatchType" />
+        </complexContent>
+    </complexType>
+
+    <complexType name="RegistrationAuthorityMatchType" abstract="true">
+        <complexContent>
+            <extension base="afp:MatchFunctorType">
+                <attribute name="registrars" type="afp:anyURIListType" use="required">
+                    <annotation>
+                        <documentation>The string values to match.</documentation>
+                    </annotation>
+                </attribute>
+                <attribute name="matchIfMetadataSilent" type="boolean">
+                    <annotation>
+                        <documentation>
+                            A boolean flag indicating whether a match should occur if the metadata does
+                            not contain an MDRPI statement (coded) default is false.
+                        </documentation>
+                    </annotation>
+                </attribute>
+            </extension>
+        </complexContent>
+    </complexType>
+
+    <complexType name="ScopeMatchesShibMDScope">
+        <annotation>
+            <documentation>
+                A match function that ensures that an attribute value's scope matches a scope given in
+                metadata for the entity or role of the attribute issuer.
+            </documentation>
+        </annotation>
+        <complexContent>
+            <extension base="afp:MatchFunctorType"/>
+        </complexContent>
+    </complexType>
+
+    <complexType name="ValueMatchesShibMDScope">
+        <annotation>
+            <documentation>
+                A match function that ensures that an attribute value's scope matches a scope given in
+                metadata for the entity or role of the attribute issuer.
+            </documentation>
+        </annotation>
+        <complexContent>
+            <extension base="afp:MatchFunctorType"/>
+        </complexContent>
+    </complexType>
+
+    <!-- SP-only matchers -->
+
+    <complexType name="NameIDQualifierString">
+        <annotation>
+            <documentation>
+                A match function that ensures that a NameID-valued attribute's qualifier(s), if set, match particular values.
+            </documentation>
+        </annotation>
+        <complexContent>
+            <extension base="afp:MatchFunctorType">
+                <attribute name="attributeID" type="afp:string">
+                    <annotation>
+                        <documentation>
+                            The ID of the attribute whose qualifiers should be matched. If no attribute ID is specified the
+                            ID of the containing attribute rule is assumed.
+                        </documentation>
+                    </annotation>
+                </attribute>
+                <attribute name="NameQualifier" type="afp:string">
+                    <annotation>
+                        <documentation>
+                            A value to require in the NameQualifier field, or if omitted, require that it match the issuing IdP's entityID.
+                        </documentation>
+                    </annotation>
+                </attribute>
+                <attribute name="SPNameQualifier" type="afp:string">
+                    <annotation>
+                        <documentation>
+                            A value to require in the SPNameQualifier field, or if omitted, require that it match the SP's entityID.
+                        </documentation>
+                    </annotation>
+                </attribute>
+            </extension>
+        </complexContent>
+    </complexType>
+
+    <complexType name="AttributeIssuerEntityMatcher">
+        <annotation>
+            <documentation>
+                A match function that checks if the attribute issuer matches pluggable criteria.
+            </documentation>
+        </annotation>
+        <complexContent>
+            <extension base="afp:EntityMatcherType"/>
+        </complexContent>
+    </complexType>
+
+    <complexType name="AttributeRequesterEntityMatcher">
+        <annotation>
+            <documentation>
+                A match function that checks if the attribute requester matches pluggable criteria.
+            </documentation>
+        </annotation>
+        <complexContent>
+            <extension base="afp:EntityMatcherType"/>
+        </complexContent>
+    </complexType>
+    
+    <complexType name="EntityMatcherType" abstract="true">
+        <complexContent>
+            <extension base="afp:MatchFunctorType">
+                <sequence>
+                    <any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+                </sequence>
+                <attribute name="matcher" type="afp:string" use="required">
+                    <annotation>
+                        <documentation>
+                            The type of plugin to apply as a matching mechanism.
+                        </documentation>
+                    </annotation>
+                </attribute>
+                <anyAttribute namespace="##any" processContents="lax"/>
+            </extension>
+        </complexContent>
+    </complexType>
+
+    <!-- Utility types -->
+
+    <simpleType name="anyURIListType">
+        <list itemType="string"/>
+    </simpleType>
+
+    <simpleType name="string">
+        <restriction base="string">
+            <minLength value="1"/>
+        </restriction>
+    </simpleType>
+
 </schema>
diff --git a/shibsp/attribute/filtering/MatchFunctor.h b/shibsp/attribute/filtering/MatchFunctor.h
index 9622665..4a102c0 100644
--- a/shibsp/attribute/filtering/MatchFunctor.h
+++ b/shibsp/attribute/filtering/MatchFunctor.h
@@ -119,27 +119,18 @@ namespace shibsp {
     /** Matches based on metadata groups of requester. */
     extern SHIBSP_API xmltooling::QName AttributeRequesterInEntityGroupType;
 
-    /** Matches based on metadata groups of requester. */
-    extern SHIBSP_API xmltooling::QName InEntityGroupType;
-
     /** Matches based on entity attributes of issuer. */
     extern SHIBSP_API xmltooling::QName AttributeIssuerEntityAttributeExactMatchType;
 
     /** Matches based on entity attributes of requester. */
     extern SHIBSP_API xmltooling::QName AttributeRequesterEntityAttributeExactMatchType;
 
-    /** Matches based on entity attributes of requester. */
-    extern SHIBSP_API xmltooling::QName EntityAttributeExactMatchType;
-
     /** Matches based on entity attributes of issuer and a regex. */
     extern SHIBSP_API xmltooling::QName AttributeIssuerEntityAttributeRegexMatchType;
 
     /** Matches based on entity attributes of requester and a regex. */
     extern SHIBSP_API xmltooling::QName AttributeRequesterEntityAttributeRegexMatchType;
 
-    /** Matches based on entity attributes of requester and a regex. */
-    extern SHIBSP_API xmltooling::QName EntityAttributeRegexMatchType;
-
     /** Matches based on issuer and pluggable criteria. */
     extern SHIBSP_API xmltooling::QName AttributeIssuerEntityMatcherType;
 
diff --git a/shibsp/attribute/filtering/impl/AttributeIssuerInEntityGroupFunctor.cpp b/shibsp/attribute/filtering/impl/AttributeIssuerInEntityGroupFunctor.cpp
index 82784c9..23a55a8 100644
--- a/shibsp/attribute/filtering/impl/AttributeIssuerInEntityGroupFunctor.cpp
+++ b/shibsp/attribute/filtering/impl/AttributeIssuerInEntityGroupFunctor.cpp
@@ -30,14 +30,21 @@
 #include "attribute/filtering/FilteringContext.h"
 #include "attribute/filtering/FilterPolicyContext.h"
 #include "attribute/filtering/MatchFunctor.h"
+#include "metadata/MetadataProviderCriteria.h"
 
+#include <xmltooling/Lockable.h>
+#include <xmltooling/util/XMLHelper.h>
 #include <saml/saml2/metadata/Metadata.h>
+#include <saml/saml2/metadata/MetadataProvider.h>
 
 using namespace opensaml::saml2md;
+using namespace xmltooling;
+using namespace std;
 
 namespace shibsp {
 
-    static const XMLCh groupID[] = UNICODE_LITERAL_7(g,r,o,u,p,I,D);
+    static const XMLCh checkAffiliations[] =    UNICODE_LITERAL_17(c,h,e,c,k,A,f,f,i,l,i,a,t,i,o,n,s);
+    static const XMLCh groupID[] =              UNICODE_LITERAL_7(g,r,o,u,p,I,D);
 
     /**
      * A match function that evaluates to true if the attribute issuer is found in metadata and is a member
@@ -46,8 +53,10 @@ namespace shibsp {
     class SHIBSP_DLLLOCAL AttributeIssuerInEntityGroupFunctor : public MatchFunctor
     {
         const XMLCh* m_group;
+        bool m_checkAffiliations;
     public:
-        AttributeIssuerInEntityGroupFunctor(const DOMElement* e) {
+        AttributeIssuerInEntityGroupFunctor(const DOMElement* e)
+                : m_checkAffiliations(XMLHelper::getAttrBool(e, false, checkAffiliations)) {
             m_group = e ? e->getAttributeNS(nullptr,groupID) : nullptr;
             if (!m_group || !*m_group)
                 throw ConfigurationException("AttributeIssuerInEntityGroup MatchFunctor requires non-empty groupID attribute.");
@@ -63,6 +72,26 @@ namespace shibsp {
                     return true;
                 group = dynamic_cast<const EntitiesDescriptor*>(group->getParent());
             }
+
+            if (m_checkAffiliations) {
+                // Use metadata to invoke the SSO service directly.
+                MetadataProvider* m = filterContext.getApplication().getMetadataProvider();
+                Locker locker(m);
+                MetadataProviderCriteria mc(filterContext.getApplication(), m_group);
+                pair<const EntityDescriptor*,const RoleDescriptor*> entity = m->getEntityDescriptor(mc);
+                if (entity.first) {
+                    const AffiliationDescriptor* affiliation = entity.first->getAffiliationDescriptor();
+                    if (affiliation) {
+                        const vector<AffiliateMember*>& members = affiliation->getAffiliateMembers();
+                        for (vector<AffiliateMember*>::const_iterator i = members.begin(); i != members.end(); ++i) {
+                            if (XMLString::equals(filterContext.getAttributeIssuer(), (*i)->getID())) {
+                                return true;
+                            }
+                        }
+                    }
+                }
+            }
+
             return false;
         }
 
diff --git a/shibsp/attribute/filtering/impl/AttributeIssuerRegexFunctor.cpp b/shibsp/attribute/filtering/impl/AttributeIssuerRegexFunctor.cpp
index 22aa0f2..39aa404 100644
--- a/shibsp/attribute/filtering/impl/AttributeIssuerRegexFunctor.cpp
+++ b/shibsp/attribute/filtering/impl/AttributeIssuerRegexFunctor.cpp
@@ -31,12 +31,15 @@
 #include "attribute/filtering/FilterPolicyContext.h"
 #include "attribute/filtering/MatchFunctor.h"
 
+#include <xmltooling/util/XMLHelper.h>
+
 #include <xercesc/util/regx/RegularExpression.hpp>
 
 namespace shibsp {
 
-    static const XMLCh options[] =  UNICODE_LITERAL_7(o,p,t,i,o,n,s);
-    static const XMLCh regex[] =    UNICODE_LITERAL_5(r,e,g,e,x);
+    static const XMLCh caseSensitive[] =    UNICODE_LITERAL_13(c,a,s,e,S,e,n,s,i,t,i,v,e);
+    static const XMLCh options[] =          UNICODE_LITERAL_7(o,p,t,i,o,n,s);
+    static const XMLCh regex[] =            UNICODE_LITERAL_5(r,e,g,e,x);
     
     /**
      * A match function that evaluates to true if the Attribute issuer matches the provided regular
@@ -50,10 +53,20 @@ namespace shibsp {
             const XMLCh* r = e ? e->getAttributeNS(nullptr, regex) : nullptr;
             if (!r || !*r)
                 throw ConfigurationException("AttributeIssuerRegex MatchFunctor requires non-empty regex attribute.");
+
             try {
-                m_regex.reset(new RegularExpression(r, e->getAttributeNS(nullptr,options)));
+                const XMLCh* opts = e->getAttributeNS(nullptr, options);
+                if (!opts) {
+                    bool flag = xmltooling::XMLHelper::getAttrBool(e, true, caseSensitive);
+                    if (!flag) {
+                        static const XMLCh i_option[] = UNICODE_LITERAL_1(i);
+                        opts = i_option;
+                    }
+                }
+
+                m_regex.reset(new RegularExpression(r, opts));
             }
-            catch (XMLException& ex) {
+            catch (const XMLException& ex) {
                 xmltooling::auto_ptr_char temp(ex.getMessage());
                 throw ConfigurationException(temp.get());
             }
@@ -62,11 +75,17 @@ namespace shibsp {
         virtual ~AttributeIssuerRegexFunctor() {}
 
         bool evaluatePolicyRequirement(const FilteringContext& filterContext) const {
-            return m_regex->matches(filterContext.getAttributeIssuer());
+            try {
+                return m_regex->matches(filterContext.getAttributeIssuer());
+            }
+            catch (const XMLException& ex) {
+                xmltooling::auto_ptr_char temp(ex.getMessage());
+                throw AttributeFilteringException(temp.get());
+            }
         }
 
         bool evaluatePermitValue(const FilteringContext& filterContext, const Attribute& attribute, size_t index) const {
-            return m_regex->matches(filterContext.getAttributeIssuer());
+            return evaluatePolicyRequirement(filterContext);
         }
     };
 
diff --git a/shibsp/attribute/filtering/impl/AttributeIssuerStringFunctor.cpp b/shibsp/attribute/filtering/impl/AttributeIssuerStringFunctor.cpp
index 0a3fa64..b4bdb43 100644
--- a/shibsp/attribute/filtering/impl/AttributeIssuerStringFunctor.cpp
+++ b/shibsp/attribute/filtering/impl/AttributeIssuerStringFunctor.cpp
@@ -35,8 +35,9 @@ using xmltooling::XMLHelper;
 
 namespace shibsp {
 
-    static const XMLCh value[] = UNICODE_LITERAL_5(v,a,l,u,e);
-    static const XMLCh ignoreCase[] = UNICODE_LITERAL_10(i,g,n,o,r,e,C,a,s,e);
+    static const XMLCh caseSensitive[] =    UNICODE_LITERAL_13(c,a,s,e,S,e,n,s,i,t,i,v,e);
+    static const XMLCh ignoreCase[] =       UNICODE_LITERAL_10(i,g,n,o,r,e,C,a,s,e);
+    static const XMLCh value[] =            UNICODE_LITERAL_5(v,a,l,u,e);
 
     /**
      * A match function that matches the attribute issuer's name against the specified value.
@@ -44,20 +45,26 @@ namespace shibsp {
     class SHIBSP_DLLLOCAL AttributeIssuerStringFunctor : public MatchFunctor
     {
         const XMLCh* m_value;
-        bool m_ignoreCase;
+        bool m_caseSensitive;
     public:
         AttributeIssuerStringFunctor(const DOMElement* e)
-            : m_value(e ? e->getAttributeNS(nullptr,value) : nullptr),
-                m_ignoreCase(XMLHelper::getAttrBool(e, false, ignoreCase)) {
+            : m_value(e ? e->getAttributeNS(nullptr, value) : nullptr), m_caseSensitive(true) {
             if (!m_value || !*m_value)
                 throw ConfigurationException("AttributeIssuerString MatchFunctor requires non-empty value attribute.");
+
+            if (e->hasAttributeNS(nullptr, caseSensitive)) {
+                m_caseSensitive = XMLHelper::getAttrBool(e, true, caseSensitive);
+            }
+            else if (e->hasAttributeNS(nullptr, ignoreCase)) {
+                m_caseSensitive = !XMLHelper::getAttrBool(e, false, ignoreCase);
+            }
         }
 
         bool evaluatePolicyRequirement(const FilteringContext& filterContext) const {
-            if (m_ignoreCase)
-                return (XMLString::compareIString(m_value, filterContext.getAttributeIssuer()) == 0);
-            else
+            if (m_caseSensitive)
                 return XMLString::equals(m_value, filterContext.getAttributeIssuer());
+            else
+                return (XMLString::compareIString(m_value, filterContext.getAttributeIssuer()) == 0);
         }
 
         bool evaluatePermitValue(const FilteringContext& filterContext, const Attribute& attribute, size_t index) const {
diff --git a/shibsp/attribute/filtering/impl/AttributeRequesterInEntityGroupFunctor.cpp b/shibsp/attribute/filtering/impl/AttributeRequesterInEntityGroupFunctor.cpp
index f9db9b4..c2b21f7 100644
--- a/shibsp/attribute/filtering/impl/AttributeRequesterInEntityGroupFunctor.cpp
+++ b/shibsp/attribute/filtering/impl/AttributeRequesterInEntityGroupFunctor.cpp
@@ -30,13 +30,20 @@
 #include "attribute/filtering/FilteringContext.h"
 #include "attribute/filtering/FilterPolicyContext.h"
 #include "attribute/filtering/MatchFunctor.h"
+#include "metadata/MetadataProviderCriteria.h"
 
+#include <xmltooling/Lockable.h>
+#include <xmltooling/util/XMLHelper.h>
 #include <saml/saml2/metadata/Metadata.h>
+#include <saml/saml2/metadata/MetadataProvider.h>
 
 using namespace opensaml::saml2md;
+using namespace xmltooling;
+using namespace std;
 
 namespace shibsp {
 
+    static const XMLCh checkAffiliations[] =    UNICODE_LITERAL_17(c,h,e,c,k,A,f,f,i,l,i,a,t,i,o,n,s);
     static const XMLCh groupID[] = UNICODE_LITERAL_7(g,r,o,u,p,I,D);
 
     /**
@@ -46,8 +53,10 @@ namespace shibsp {
     class SHIBSP_DLLLOCAL AttributeRequesterInEntityGroupFunctor : public MatchFunctor
     {
         const XMLCh* m_group;
+        bool m_checkAffiliations;
     public:
-        AttributeRequesterInEntityGroupFunctor(const DOMElement* e) {
+        AttributeRequesterInEntityGroupFunctor(const DOMElement* e)
+                : m_checkAffiliations(XMLHelper::getAttrBool(e, false, checkAffiliations)) {
             m_group = e ? e->getAttributeNS(nullptr,groupID) : nullptr;
             if (!m_group || !*m_group)
                 throw ConfigurationException("AttributeRequesterInEntityGroup MatchFunctor requires non-empty groupID attribute.");
@@ -63,6 +72,26 @@ namespace shibsp {
                     return true;
                 group = dynamic_cast<const EntitiesDescriptor*>(group->getParent());
             }
+
+            if (m_checkAffiliations) {
+                // Use metadata to invoke the SSO service directly.
+                MetadataProvider* m = filterContext.getApplication().getMetadataProvider();
+                Locker locker(m);
+                MetadataProviderCriteria mc(filterContext.getApplication(), m_group);
+                pair<const EntityDescriptor*,const RoleDescriptor*> entity = m->getEntityDescriptor(mc);
+                if (entity.first) {
+                    const AffiliationDescriptor* affiliation = entity.first->getAffiliationDescriptor();
+                    if (affiliation) {
+                        const vector<AffiliateMember*>& members = affiliation->getAffiliateMembers();
+                        for (vector<AffiliateMember*>::const_iterator i = members.begin(); i != members.end(); ++i) {
+                            if (XMLString::equals(filterContext.getAttributeRequester(), (*i)->getID())) {
+                                return true;
+                            }
+                        }
+                    }
+                }
+            }
+
             return false;
         }
 
diff --git a/shibsp/attribute/filtering/impl/AttributeRequesterRegexFunctor.cpp b/shibsp/attribute/filtering/impl/AttributeRequesterRegexFunctor.cpp
index 9e42498..80095a4 100644
--- a/shibsp/attribute/filtering/impl/AttributeRequesterRegexFunctor.cpp
+++ b/shibsp/attribute/filtering/impl/AttributeRequesterRegexFunctor.cpp
@@ -31,12 +31,15 @@
 #include "attribute/filtering/FilterPolicyContext.h"
 #include "attribute/filtering/MatchFunctor.h"
 
+#include <xmltooling/util/XMLHelper.h>
+
 #include <xercesc/util/regx/RegularExpression.hpp>
 
 namespace shibsp {
 
-    static const XMLCh options[] =  UNICODE_LITERAL_7(o,p,t,i,o,n,s);
-    static const XMLCh regex[] =    UNICODE_LITERAL_5(r,e,g,e,x);
+    static const XMLCh caseSensitive[] =    UNICODE_LITERAL_13(c,a,s,e,S,e,n,s,i,t,i,v,e);
+    static const XMLCh options[] =          UNICODE_LITERAL_7(o,p,t,i,o,n,s);
+    static const XMLCh regex[] =            UNICODE_LITERAL_5(r,e,g,e,x);
     
     /**
      * A match function that evaluates to true if the Attribute requester matches the provided regular
@@ -50,10 +53,20 @@ namespace shibsp {
             const XMLCh* r = e ? e->getAttributeNS(nullptr, regex) : nullptr;
             if (!r || !*r)
                 throw ConfigurationException("AttributeRequesterRegex MatchFunctor requires non-empty regex attribute.");
+
             try {
-                m_regex.reset(new RegularExpression(r, e->getAttributeNS(nullptr, options)));
+                const XMLCh* opts = e->getAttributeNS(nullptr, options);
+                if (!opts) {
+                    bool flag = xmltooling::XMLHelper::getAttrBool(e, true, caseSensitive);
+                    if (!flag) {
+                        static const XMLCh i_option[] = UNICODE_LITERAL_1(i);
+                        opts = i_option;
+                    }
+                }
+
+                m_regex.reset(new RegularExpression(r, opts));
             }
-            catch (XMLException& ex) {
+            catch (const XMLException& ex) {
                 xmltooling::auto_ptr_char temp(ex.getMessage());
                 throw ConfigurationException(temp.get());
             }
@@ -62,11 +75,17 @@ namespace shibsp {
         virtual ~AttributeRequesterRegexFunctor() {}
 
         bool evaluatePolicyRequirement(const FilteringContext& filterContext) const {
-            return m_regex->matches(filterContext.getAttributeRequester());
+            try {
+                return m_regex->matches(filterContext.getAttributeRequester());
+            }
+            catch (const XMLException& ex) {
+                xmltooling::auto_ptr_char temp(ex.getMessage());
+                throw AttributeFilteringException(temp.get());
+            }
         }
 
         bool evaluatePermitValue(const FilteringContext& filterContext, const Attribute& attribute, size_t index) const {
-            return m_regex->matches(filterContext.getAttributeRequester());
+            return evaluatePolicyRequirement(filterContext);
         }
     };
 
diff --git a/shibsp/attribute/filtering/impl/AttributeRequesterStringFunctor.cpp b/shibsp/attribute/filtering/impl/AttributeRequesterStringFunctor.cpp
index bf765c3..7d4b42a 100644
--- a/shibsp/attribute/filtering/impl/AttributeRequesterStringFunctor.cpp
+++ b/shibsp/attribute/filtering/impl/AttributeRequesterStringFunctor.cpp
@@ -35,8 +35,9 @@ using xmltooling::XMLHelper;
 
 namespace shibsp {
 
-    static const XMLCh value[] = UNICODE_LITERAL_5(v,a,l,u,e);
-    static const XMLCh ignoreCase[] = UNICODE_LITERAL_10(i,g,n,o,r,e,C,a,s,e);
+    static const XMLCh caseSensitive[] =    UNICODE_LITERAL_13(c,a,s,e,S,e,n,s,i,t,i,v,e);
+    static const XMLCh ignoreCase[] =       UNICODE_LITERAL_10(i,g,n,o,r,e,C,a,s,e);
+    static const XMLCh value[] =            UNICODE_LITERAL_5(v,a,l,u,e);
 
     /**
      * A match function that matches the attribute requester's name against the specified value.
@@ -44,20 +45,26 @@ namespace shibsp {
     class SHIBSP_DLLLOCAL AttributeRequesterStringFunctor : public MatchFunctor
     {
         const XMLCh* m_value;
-        bool m_ignoreCase;
+        bool m_caseSensitive;
     public:
         AttributeRequesterStringFunctor(const DOMElement* e)
-                : m_value(e ? e->getAttributeNS(nullptr,value) : nullptr),
-                    m_ignoreCase(XMLHelper::getAttrBool(e, false, ignoreCase)) {
+                : m_value(e ? e->getAttributeNS(nullptr,value) : nullptr), m_caseSensitive(true) {
             if (!m_value || !*m_value)
                 throw ConfigurationException("AttributeRequesterString MatchFunctor requires non-empty value attribute.");
+
+            if (e->hasAttributeNS(nullptr, caseSensitive)) {
+                m_caseSensitive = XMLHelper::getAttrBool(e, true, caseSensitive);
+            }
+            else if (e->hasAttributeNS(nullptr, ignoreCase)) {
+                m_caseSensitive = !XMLHelper::getAttrBool(e, false, ignoreCase);
+            }
         }
 
         bool evaluatePolicyRequirement(const FilteringContext& filterContext) const {
-            if (m_ignoreCase)
-                return (XMLString::compareIString(m_value, filterContext.getAttributeRequester()) == 0);
-            else
+            if (m_caseSensitive)
                 return XMLString::equals(m_value, filterContext.getAttributeRequester());
+            else
+                return (XMLString::compareIString(m_value, filterContext.getAttributeRequester()) == 0);
         }
 
         bool evaluatePermitValue(const FilteringContext& filterContext, const Attribute& attribute, size_t index) const {
diff --git a/shibsp/attribute/filtering/impl/AttributeScopeRegexFunctor.cpp b/shibsp/attribute/filtering/impl/AttributeScopeRegexFunctor.cpp
index c521143..da0f6bc 100644
--- a/shibsp/attribute/filtering/impl/AttributeScopeRegexFunctor.cpp
+++ b/shibsp/attribute/filtering/impl/AttributeScopeRegexFunctor.cpp
@@ -42,9 +42,10 @@ using namespace std;
 
 namespace shibsp {
 
-    static const XMLCh attributeID[] =  UNICODE_LITERAL_11(a,t,t,r,i,b,u,t,e,I,D);
-    static const XMLCh options[] =  UNICODE_LITERAL_7(o,p,t,i,o,n,s);
-    static const XMLCh regex[] =    UNICODE_LITERAL_5(r,e,g,e,x);
+    static const XMLCh attributeID[] =      UNICODE_LITERAL_11(a,t,t,r,i,b,u,t,e,I,D);
+    static const XMLCh caseSensitive[] =    UNICODE_LITERAL_13(c,a,s,e,S,e,n,s,i,t,i,v,e);
+    static const XMLCh options[] =          UNICODE_LITERAL_7(o,p,t,i,o,n,s);
+    static const XMLCh regex[] =            UNICODE_LITERAL_5(r,e,g,e,x);
 
     /**
      * A match function that evaluates an attribute value's scope against the provided regular expression.
@@ -62,10 +63,20 @@ namespace shibsp {
             const XMLCh* r = e ? e->getAttributeNS(nullptr, regex) : nullptr;
             if (!r || !*r)
                 throw ConfigurationException("AttributeScopeRegex MatchFunctor requires non-empty regex attribute.");
+
             try {
-                m_regex.reset(new RegularExpression(r, e->getAttributeNS(nullptr, options)));
+                const XMLCh* opts = e->getAttributeNS(nullptr, options);
+                if (!opts) {
+                    bool flag = xmltooling::XMLHelper::getAttrBool(e, true, caseSensitive);
+                    if (!flag) {
+                        static const XMLCh i_option[] = UNICODE_LITERAL_1(i);
+                        opts = i_option;
+                    }
+                }
+
+                m_regex.reset(new RegularExpression(r, opts));
             }
-            catch (XMLException& ex) {
+            catch (const XMLException& ex) {
                 xmltooling::auto_ptr_char temp(ex.getMessage());
                 throw ConfigurationException(temp.get());
             }
@@ -114,5 +125,11 @@ bool AttributeScopeRegexFunctor::matches(const Attribute& attribute, size_t inde
     if (!val)
         return false;
     auto_arrayptr<XMLCh> temp(fromUTF8(val));
-    return m_regex->matches(temp.get());
+    try {
+        return m_regex->matches(temp.get());
+    }
+    catch (const XMLException& ex) {
+        xmltooling::auto_ptr_char temp(ex.getMessage());
+        throw AttributeFilteringException(temp.get());
+    }
 }
diff --git a/shibsp/attribute/filtering/impl/AttributeScopeStringFunctor.cpp b/shibsp/attribute/filtering/impl/AttributeScopeStringFunctor.cpp
index a2252e3..039801c 100644
--- a/shibsp/attribute/filtering/impl/AttributeScopeStringFunctor.cpp
+++ b/shibsp/attribute/filtering/impl/AttributeScopeStringFunctor.cpp
@@ -40,9 +40,10 @@ using namespace std;
 
 namespace shibsp {
 
-    static const XMLCh attributeID[] =  UNICODE_LITERAL_11(a,t,t,r,i,b,u,t,e,I,D);
-    static const XMLCh ignoreCase[] =   UNICODE_LITERAL_10(i,g,n,o,r,e,C,a,s,e);
-    static const XMLCh value[] =        UNICODE_LITERAL_5(v,a,l,u,e);
+    static const XMLCh attributeID[] =      UNICODE_LITERAL_11(a,t,t,r,i,b,u,t,e,I,D);
+    static const XMLCh caseSensitive[] =    UNICODE_LITERAL_13(c,a,s,e,S,e,n,s,i,t,i,v,e);
+    static const XMLCh ignoreCase[] =       UNICODE_LITERAL_10(i,g,n,o,r,e,C,a,s,e);
+    static const XMLCh value[] =            UNICODE_LITERAL_5(v,a,l,u,e);
 
     /**
      * A match function that matches the scope of an attribute value against the specified value.
@@ -51,7 +52,7 @@ namespace shibsp {
     {
         string m_attributeID;
         auto_arrayptr<char> m_value;
-        bool m_ignoreCase;
+        bool m_caseSensitive;
 
         bool hasScope(const FilteringContext& filterContext) const;
 
@@ -59,10 +60,17 @@ namespace shibsp {
         AttributeScopeStringFunctor(const DOMElement* e)
             : m_attributeID(XMLHelper::getAttrString(e, nullptr, attributeID)),
                 m_value(e ? toUTF8(e->getAttributeNS(nullptr, value)) : nullptr),
-                m_ignoreCase(XMLHelper::getAttrBool(e, false, ignoreCase)) {
+                m_caseSensitive(true) {
             if (!m_value.get() || !*m_value.get()) {
                 throw ConfigurationException("AttributeScopeString MatchFunctor requires non-empty value attribute.");
             }
+
+            if (e->hasAttributeNS(nullptr, caseSensitive)) {
+                m_caseSensitive = XMLHelper::getAttrBool(e, true, caseSensitive);
+            }
+            else if (e->hasAttributeNS(nullptr, ignoreCase)) {
+                m_caseSensitive = !XMLHelper::getAttrBool(e, false, ignoreCase);
+            }
         }
 
         virtual ~AttributeScopeStringFunctor() {}
@@ -79,7 +87,7 @@ namespace shibsp {
                 if (!scope) {
                     return false;
                 }
-                else if (m_ignoreCase) {
+                else if (!m_caseSensitive) {
 #ifdef HAVE_STRCASECMP
                     return !strcasecmp(scope, m_value.get());
 #else
@@ -114,7 +122,7 @@ bool AttributeScopeStringFunctor::hasScope(const FilteringContext& filterContext
             if (!scope) {
                 return false;
             }
-            else if (m_ignoreCase) {
+            else if (!m_caseSensitive) {
 #ifdef HAVE_STRCASECMP
                 if (!strcasecmp(scope, m_value.get()))
                     return true;
diff --git a/shibsp/attribute/filtering/impl/AttributeValueRegexFunctor.cpp b/shibsp/attribute/filtering/impl/AttributeValueRegexFunctor.cpp
index a6b2afa..3d1d236 100644
--- a/shibsp/attribute/filtering/impl/AttributeValueRegexFunctor.cpp
+++ b/shibsp/attribute/filtering/impl/AttributeValueRegexFunctor.cpp
@@ -42,9 +42,10 @@ using namespace std;
 
 namespace shibsp {
 
-    static const XMLCh attributeID[] =  UNICODE_LITERAL_11(a,t,t,r,i,b,u,t,e,I,D);
-    static const XMLCh options[] =  UNICODE_LITERAL_7(o,p,t,i,o,n,s);
-    static const XMLCh regex[] =    UNICODE_LITERAL_5(r,e,g,e,x);
+    static const XMLCh attributeID[] =      UNICODE_LITERAL_11(a,t,t,r,i,b,u,t,e,I,D);
+    static const XMLCh caseSensitive[] =    UNICODE_LITERAL_13(c,a,s,e,S,e,n,s,i,t,i,v,e);
+    static const XMLCh options[] =          UNICODE_LITERAL_7(o,p,t,i,o,n,s);
+    static const XMLCh regex[] =            UNICODE_LITERAL_5(r,e,g,e,x);
 
     /**
      * A match function that evaluates an attribute's value against the provided regular expression.
@@ -63,10 +64,20 @@ namespace shibsp {
             const XMLCh* r = e ? e->getAttributeNS(nullptr, regex) : nullptr;
             if (!r || !*r)
                 throw ConfigurationException("AttributeValueRegex MatchFunctor requires non-empty regex attribute.");
+
             try {
-                m_regex.reset(new RegularExpression(r, e->getAttributeNS(nullptr, options)));
+                const XMLCh* opts = e->getAttributeNS(nullptr, options);
+                if (!opts) {
+                    bool flag = xmltooling::XMLHelper::getAttrBool(e, true, caseSensitive);
+                    if (!flag) {
+                        static const XMLCh i_option[] = UNICODE_LITERAL_1(i);
+                        opts = i_option;
+                    }
+                }
+
+                m_regex.reset(new RegularExpression(r, opts));
             }
-            catch (XMLException& ex) {
+            catch (const XMLException& ex) {
                 xmltooling::auto_ptr_char temp(ex.getMessage());
                 throw ConfigurationException(temp.get());
             }
@@ -115,5 +126,11 @@ bool AttributeValueRegexFunctor::matches(const Attribute& attribute, size_t inde
     if (!val)
         return false;
     auto_arrayptr<XMLCh> temp(fromUTF8(val));
-    return m_regex->matches(temp.get());
+    try {
+        return m_regex->matches(temp.get());
+    }
+    catch (const XMLException& ex) {
+        xmltooling::auto_ptr_char temp(ex.getMessage());
+        throw AttributeFilteringException(temp.get());
+    }
 }
diff --git a/shibsp/attribute/filtering/impl/AttributeValueStringFunctor.cpp b/shibsp/attribute/filtering/impl/AttributeValueStringFunctor.cpp
index dbcc4a4..38285e1 100644
--- a/shibsp/attribute/filtering/impl/AttributeValueStringFunctor.cpp
+++ b/shibsp/attribute/filtering/impl/AttributeValueStringFunctor.cpp
@@ -40,9 +40,10 @@ using namespace std;
 
 namespace shibsp {
 
-    static const XMLCh attributeID[] =  UNICODE_LITERAL_11(a,t,t,r,i,b,u,t,e,I,D);
-    static const XMLCh value[] =        UNICODE_LITERAL_5(v,a,l,u,e);
-    static const XMLCh ignoreCase[] =   UNICODE_LITERAL_10(i,g,n,o,r,e,C,a,s,e);
+    static const XMLCh attributeID[] =      UNICODE_LITERAL_11(a,t,t,r,i,b,u,t,e,I,D);
+    static const XMLCh caseSensitive[] =    UNICODE_LITERAL_13(c,a,s,e,S,e,n,s,i,t,i,v,e);
+    static const XMLCh ignoreCase[] =       UNICODE_LITERAL_10(i,g,n,o,r,e,C,a,s,e);
+    static const XMLCh value[] =            UNICODE_LITERAL_5(v,a,l,u,e);
 
     /**
      * A match function that matches the value of an attribute against the specified value.
@@ -62,11 +63,18 @@ namespace shibsp {
             if (!m_value.get() || !*m_value.get()) {
                 throw ConfigurationException("AttributeValueString MatchFunctor requires non-empty value attribute.");
             }
-            if (e && e->hasAttributeNS(nullptr, ignoreCase)) {
-                Category::getInstance(SHIBSP_LOGCAT ".AttributeFilter").warn(
+
+            if (e->hasAttributeNS(nullptr, ignoreCase)) {
+                Category::getInstance(SHIBSP_LOGCAT ".AttributeFilter.AttributeValueString").warn(
                     "ignoreCase property ignored by AttributeValueString MatchFunctor in favor of attribute's caseSensitive property"
                     );
             }
+
+            if (e->hasAttributeNS(nullptr, caseSensitive)) {
+                Category::getInstance(SHIBSP_LOGCAT ".AttributeFilter.AttributeValueString").warn(
+                    "caseSensitive property ignored by AttributeValueString MatchFunctor in favor of attribute's caseSensitive property"
+                );
+            }
         }
 
         virtual ~AttributeValueStringFunctor() {}
diff --git a/shibsp/attribute/filtering/impl/AuthenticationMethodRegexFunctor.cpp b/shibsp/attribute/filtering/impl/AuthenticationMethodRegexFunctor.cpp
index e423502..825ba21 100644
--- a/shibsp/attribute/filtering/impl/AuthenticationMethodRegexFunctor.cpp
+++ b/shibsp/attribute/filtering/impl/AuthenticationMethodRegexFunctor.cpp
@@ -31,12 +31,15 @@
 #include "attribute/filtering/FilterPolicyContext.h"
 #include "attribute/filtering/MatchFunctor.h"
 
+#include <xmltooling/util/XMLHelper.h>
+
 #include <xercesc/util/regx/RegularExpression.hpp>
 
 namespace shibsp {
 
-    static const XMLCh options[] =  UNICODE_LITERAL_7(o,p,t,i,o,n,s);
-    static const XMLCh regex[] =    UNICODE_LITERAL_5(r,e,g,e,x);
+    static const XMLCh caseSensitive[] =    UNICODE_LITERAL_13(c,a,s,e,S,e,n,s,i,t,i,v,e);
+    static const XMLCh options[] =          UNICODE_LITERAL_7(o,p,t,i,o,n,s);
+    static const XMLCh regex[] =            UNICODE_LITERAL_5(r,e,g,e,x);
     
     /**
      * A match function that evaluates to true if the user's authentication method matches the provided regular
@@ -50,10 +53,20 @@ namespace shibsp {
             const XMLCh* r = e ? e->getAttributeNS(nullptr, regex) : nullptr;
             if (!r || !*r)
                 throw ConfigurationException("AuthenticationMethodRegex MatchFunctor requires non-empty regex attribute.");
+
             try {
-                m_regex.reset(new RegularExpression(r, e->getAttributeNS(nullptr, options)));
+                const XMLCh* opts = e->getAttributeNS(nullptr, options);
+                if (!opts) {
+                    bool flag = xmltooling::XMLHelper::getAttrBool(e, true, caseSensitive);
+                    if (!flag) {
+                        static const XMLCh i_option[] = UNICODE_LITERAL_1(i);
+                        opts = i_option;
+                    }
+                }
+
+                m_regex.reset(new RegularExpression(r, opts));
             }
-            catch (XMLException& ex) {
+            catch (const XMLException& ex) {
                 xmltooling::auto_ptr_char temp(ex.getMessage());
                 throw ConfigurationException(temp.get());
             }
@@ -62,11 +75,17 @@ namespace shibsp {
         virtual ~AuthenticationMethodRegexFunctor() {}
 
         bool evaluatePolicyRequirement(const FilteringContext& filterContext) const {
-            return (m_regex->matches(filterContext.getAuthnContextClassRef()) || m_regex->matches(filterContext.getAuthnContextDeclRef()));
+            try {
+                return (m_regex->matches(filterContext.getAuthnContextClassRef()) || m_regex->matches(filterContext.getAuthnContextDeclRef()));
+            }
+            catch (const XMLException& ex) {
+                xmltooling::auto_ptr_char temp(ex.getMessage());
+                throw AttributeFilteringException(temp.get());
+            }
         }
 
         bool evaluatePermitValue(const FilteringContext& filterContext, const Attribute& attribute, size_t index) const {
-            return (m_regex->matches(filterContext.getAuthnContextClassRef()) || m_regex->matches(filterContext.getAuthnContextDeclRef()));
+            return evaluatePolicyRequirement(filterContext);
         }
     };
 
diff --git a/shibsp/attribute/filtering/impl/AuthenticationMethodStringFunctor.cpp b/shibsp/attribute/filtering/impl/AuthenticationMethodStringFunctor.cpp
index 9eb542d..c817a40 100644
--- a/shibsp/attribute/filtering/impl/AuthenticationMethodStringFunctor.cpp
+++ b/shibsp/attribute/filtering/impl/AuthenticationMethodStringFunctor.cpp
@@ -37,8 +37,9 @@ using xmltooling::XMLHelper;
 
 namespace shibsp {
 
-    static const XMLCh value[] = UNICODE_LITERAL_5(v,a,l,u,e);
-    static const XMLCh ignoreCase[] = UNICODE_LITERAL_10(i,g,n,o,r,e,C,a,s,e);
+    static const XMLCh caseSensitive[] =    UNICODE_LITERAL_13(c,a,s,e,S,e,n,s,i,t,i,v,e);
+    static const XMLCh ignoreCase[] =       UNICODE_LITERAL_10(i,g,n,o,r,e,C,a,s,e);
+    static const XMLCh value[] =            UNICODE_LITERAL_5(v,a,l,u,e);
 
     /**
      * Match functor that compares the user's authentication method against a given string.
@@ -46,16 +47,23 @@ namespace shibsp {
     class SHIBSP_DLLLOCAL AuthenticationMethodStringFunctor : public MatchFunctor
     {
         const XMLCh* m_value;
-        bool m_ignoreCase;
+        bool m_caseSensitive;
     public:
         AuthenticationMethodStringFunctor(const DOMElement* e)
-            : m_value(e ? e->getAttributeNS(nullptr,value) : nullptr), m_ignoreCase(XMLHelper::getAttrBool(e, false, ignoreCase)) {
+            : m_value(e ? e->getAttributeNS(nullptr,value) : nullptr), m_caseSensitive(true) {
             if (!m_value || !*m_value)
                 throw ConfigurationException("AuthenticationMethodString MatchFunctor requires non-empty value attribute.");
+
+            if (e->hasAttributeNS(nullptr, caseSensitive)) {
+                m_caseSensitive = XMLHelper::getAttrBool(e, true, caseSensitive);
+            }
+            else if (e->hasAttributeNS(nullptr, ignoreCase)) {
+                m_caseSensitive = !XMLHelper::getAttrBool(e, false, ignoreCase);
+            }
         }
 
         bool evaluatePolicyRequirement(const FilteringContext& filterContext) const {
-            if (m_ignoreCase)
+            if (!m_caseSensitive)
                 return (XMLString::compareIString(m_value, filterContext.getAuthnContextClassRef()) == 0 ||
                     XMLString::compareIString(m_value, filterContext.getAuthnContextDeclRef()) == 0);
             else
diff --git a/shibsp/attribute/filtering/impl/MatchFunctor.cpp b/shibsp/attribute/filtering/impl/MatchFunctor.cpp
index e1e029d..5bbfc71 100644
--- a/shibsp/attribute/filtering/impl/MatchFunctor.cpp
+++ b/shibsp/attribute/filtering/impl/MatchFunctor.cpp
@@ -38,14 +38,18 @@ using namespace std;
 #define DECL_FACTORY(name) \
     SHIBSP_DLLLOCAL PluginManager< MatchFunctor,xmltooling::QName,pair<const FilterPolicyContext*,const DOMElement*> >::Factory name##Factory
 
+#define DECL_PUBLIC_QNAME(name,lit) \
+    xmltooling::QName shibsp::name##Type(shibspconstants::SHIB2ATTRIBUTEFILTER_NS, lit)
+
 #define DECL_BASIC_QNAME(name,lit) \
-    xmltooling::QName shibsp::name##Type(shibspconstants::SHIB2ATTRIBUTEFILTER_MF_BASIC_NS, lit)
+    SHIBSP_DLLLOCAL static xmltooling::QName Deprecated##name##Type(shibspconstants::SHIB2ATTRIBUTEFILTER_MF_BASIC_NS, lit)
 
 #define DECL_SAML_QNAME(name,lit) \
-    xmltooling::QName shibsp::name##Type(shibspconstants::SHIB2ATTRIBUTEFILTER_MF_SAML_NS, lit)
+    SHIBSP_DLLLOCAL static xmltooling::QName Deprecated##name##Type(shibspconstants::SHIB2ATTRIBUTEFILTER_MF_SAML_NS, lit)
 
 #define REGISTER_FACTORY(name) \
-    mgr.registerFactory(name##Type, name##Factory)
+    mgr.registerFactory(name##Type, name##Factory); \
+    mgr.registerFactory(Deprecated##name##Type, name##Factory)
 
 namespace shibsp {
     DECL_FACTORY(AnyMatchFunctor);
@@ -82,71 +86,164 @@ namespace shibsp {
     static const XMLCh AND[] =                          UNICODE_LITERAL_3(A,N,D);
     static const XMLCh OR[] =                           UNICODE_LITERAL_2(O,R);
     static const XMLCh NOT[] =                          UNICODE_LITERAL_3(N,O,T);
+
     static const XMLCh AttributeIssuerString[] =        UNICODE_LITERAL_21(A,t,t,r,i,b,u,t,e,I,s,s,u,e,r,S,t,r,i,n,g);
+    static const XMLCh Issuer[] =                       UNICODE_LITERAL_6(I,s,s,u,e,r);
+
     static const XMLCh AttributeRequesterString[] =     UNICODE_LITERAL_24(A,t,t,r,i,b,u,t,e,R,e,q,u,e,s,t,e,r,S,t,r,i,n,g);
+    static const XMLCh Requester[] =                    UNICODE_LITERAL_9(R,e,q,u,e,s,t,e,r);
+
     static const XMLCh AuthenticationMethodString[] =   UNICODE_LITERAL_26(A,u,t,h,e,n,t,i,c,a,t,i,o,n,M,e,t,h,o,d,S,t,r,i,n,g);
+    static const XMLCh AuthenticationMethod[] =         UNICODE_LITERAL_20(A,u,t,h,e,n,t,i,c,a,t,i,o,n,M,e,t,h,o,d);
+
     static const XMLCh AttributeValueString[] =         UNICODE_LITERAL_20(A,t,t,r,i,b,u,t,e,V,a,l,u,e,S,t,r,i,n,g);
+    static const XMLCh Value[] =                        UNICODE_LITERAL_5(V,a,l,u,e);
+
     static const XMLCh AttributeScopeString[] =         UNICODE_LITERAL_20(A,t,t,r,i,b,u,t,e,S,c,o,p,e,S,t,r,i,n,g);
+    static const XMLCh Scope[] =                        UNICODE_LITERAL_5(S,c,o,p,e);
+
     static const XMLCh AttributeIssuerRegex[] =         UNICODE_LITERAL_20(A,t,t,r,i,b,u,t,e,I,s,s,u,e,r,R,e,g,e,x);
+    static const XMLCh IssuerRegex[] =                  UNICODE_LITERAL_11(I,s,s,u,e,r,R,e,g,e,x);
+
     static const XMLCh AttributeRequesterRegex[] =      UNICODE_LITERAL_23(A,t,t,r,i,b,u,t,e,R,e,q,u,e,s,t,e,r,R,e,g,e,x);
+    static const XMLCh RequesterRegex[] =               UNICODE_LITERAL_14(R,e,q,u,e,s,t,e,r,R,e,g,e,x);
+
     static const XMLCh AuthenticationMethodRegex[] =    UNICODE_LITERAL_25(A,u,t,h,e,n,t,i,c,a,t,i,o,n,M,e,t,h,o,d,R,e,g,e,x);
+
     static const XMLCh AttributeValueRegex[] =          UNICODE_LITERAL_19(A,t,t,r,i,b,u,t,e,V,a,l,u,e,R,e,g,e,x);
+    static const XMLCh ValueRegex[] =                   UNICODE_LITERAL_10(V,a,l,u,e,R,e,g,e,x);
+
     static const XMLCh AttributeScopeRegex[] =          UNICODE_LITERAL_19(A,t,t,r,i,b,u,t,e,S,c,o,p,e,R,e,g,e,x);
+    static const XMLCh ScopeRegex[] =                   UNICODE_LITERAL_10(S,c,o,p,e,R,e,g,e,x);
+
     static const XMLCh NumberOfAttributeValues[] =      UNICODE_LITERAL_23(N,u,m,b,e,r,O,f,A,t,t,r,i,b,u,t,e,V,a,l,u,e,s);
-    static const XMLCh AttributeIssuerInEntityGroup[] = UNICODE_LITERAL_28(A,t,t,r,i,b,u,t,e,I,s,s,u,e,r,I,n,E,n,t,i,t,y,G,r,o,u,p);
-    static const XMLCh AttributeRequesterInEntityGroup[] = UNICODE_LITERAL_31(A,t,t,r,i,b,u,t,e,R,e,q,u,e,s,t,e,r,I,n,E,n,t,i,t,y,G,r,o,u,p);
-    static const XMLCh InEntityGroup[] = 				UNICODE_LITERAL_13(I,n,E,n,t,i,t,y,G,r,o,u,p);
+
     static const XMLCh AttributeIssuerEntityAttributeExactMatch[] = UNICODE_LITERAL_40(A,t,t,r,i,b,u,t,e,I,s,s,u,e,r,E,n,t,i,t,y,A,t,t,r,i,b,u,t,e,E,x,a,c,t,M,a,t,c,h);
+    static const XMLCh IssuerEntityAttributeExactMatch[] = UNICODE_LITERAL_31(I,s,s,u,e,r,E,n,t,i,t,y,A,t,t,r,i,b,u,t,e,E,x,a,c,t,M,a,t,c,h);
+
     static const XMLCh AttributeRequesterEntityAttributeExactMatch[] = UNICODE_LITERAL_43(A,t,t,r,i,b,u,t,e,R,e,q,u,e,s,t,e,r,E,n,t,i,t,y,A,t,t,r,i,b,u,t,e,E,x,a,c,t,M,a,t,c,h);
     static const XMLCh EntityAttributeExactMatch[] = 	UNICODE_LITERAL_25(E,n,t,i,t,y,A,t,t,r,i,b,u,t,e,E,x,a,c,t,M,a,t,c,h);
+
     static const XMLCh AttributeIssuerEntityAttributeRegexMatch[] = UNICODE_LITERAL_40(A,t,t,r,i,b,u,t,e,I,s,s,u,e,r,E,n,t,i,t,y,A,t,t,r,i,b,u,t,e,R,e,g,e,x,M,a,t,c,h);
+    static const XMLCh IssuerEntityAttributeRegexMatch[] = UNICODE_LITERAL_31(I,s,s,u,e,r,E,n,t,i,t,y,A,t,t,r,i,b,u,t,e,R,e,g,e,x,M,a,t,c,h);
+
     static const XMLCh AttributeRequesterEntityAttributeRegexMatch[] = UNICODE_LITERAL_43(A,t,t,r,i,b,u,t,e,R,e,q,u,e,s,t,e,r,E,n,t,i,t,y,A,t,t,r,i,b,u,t,e,R,e,g,e,x,M,a,t,c,h);
     static const XMLCh EntityAttributeRegexMatch[] = 	UNICODE_LITERAL_25(E,n,t,i,t,y,A,t,t,r,i,b,u,t,e,R,e,g,e,x,M,a,t,c,h);
-    static const XMLCh AttributeIssuerEntityMatcher[] = UNICODE_LITERAL_28(A,t,t,r,i,b,u,t,e,I,s,s,u,e,r,E,n,t,i,t,y,M,a,t,c,h,e,r);
-    static const XMLCh AttributeRequesterEntityMatcher[] = UNICODE_LITERAL_31(A,t,t,r,i,b,u,t,e,R,e,q,u,e,s,t,e,r,E,n,t,i,t,y,M,a,t,c,h,e,r);
+
+    static const XMLCh AttributeIssuerInEntityGroup[] = UNICODE_LITERAL_28(A,t,t,r,i,b,u,t,e,I,s,s,u,e,r,I,n,E,n,t,i,t,y,G,r,o,u,p);
+    static const XMLCh IssuerInEntityGroup[] =          UNICODE_LITERAL_19(I,s,s,u,e,r,I,n,E,n,t,i,t,y,G,r,o,u,p);
+
+    static const XMLCh AttributeRequesterInEntityGroup[] = UNICODE_LITERAL_31(A,t,t,r,i,b,u,t,e,R,e,q,u,e,s,t,e,r,I,n,E,n,t,i,t,y,G,r,o,u,p);
+    static const XMLCh InEntityGroup[] = 				UNICODE_LITERAL_13(I,n,E,n,t,i,t,y,G,r,o,u,p);
+
+    static const XMLCh AttributeIssuerRegistrationAuthority[] = UNICODE_LITERAL_36(A,t,t,r,i,b,u,t,e,I,s,s,u,e,r,R,e,g,i,s,t,r,a,t,i,o,n,A,u,t,h,o,r,i,t,y);
+    static const XMLCh IssuerRegistrationAuthority[] = UNICODE_LITERAL_27(I,s,s,u,e,r,R,e,g,i,s,t,r,a,t,i,o,n,A,u,t,h,o,r,i,t,y);
+
+    static const XMLCh RegistrationAuthority[] =        UNICODE_LITERAL_21(R,e,g,i,s,t,r,a,t,i,o,n,A,u,t,h,o,r,i,t,y);
+
     static const XMLCh AttributeScopeMatchesShibMDScope[] = UNICODE_LITERAL_32(A,t,t,r,i,b,u,t,e,S,c,o,p,e,M,a,t,c,h,e,s,S,h,i,b,M,D,S,c,o,p,e);
+    static const XMLCh ScopeMatchesShibMDScope[] =          UNICODE_LITERAL_23(S,c,o,p,e,M,a,t,c,h,e,s,S,h,i,b,M,D,S,c,o,p,e);
+
     static const XMLCh AttributeValueMatchesShibMDScope[] = UNICODE_LITERAL_32(A,t,t,r,i,b,u,t,e,V,a,l,u,e,M,a,t,c,h,e,s,S,h,i,b,M,D,S,c,o,p,e);
+    static const XMLCh ValueMatchesShibMDScope[] =          UNICODE_LITERAL_23(V,a,l,u,e,M,a,t,c,h,e,s,S,h,i,b,M,D,S,c,o,p,e);
+
     static const XMLCh NameIDQualifierString[] =        UNICODE_LITERAL_21(N,a,m,e,I,D,Q,u,a,l,i,f,i,e,r,S,t,r,i,n,g);
-    static const XMLCh AttributeIssuerRegistrationAuthority[] = UNICODE_LITERAL_36(A,t,t,r,i,b,u,t,e,I,s,s,u,e,r,R,e,g,i,s,t,r,a,t,i,o,n,A,u,t,h,o,r,i,t,y);
-    static const XMLCh RegistrationAuthority[] =        UNICODE_LITERAL_21(R,e,g,i,s,t,r,a,t,i,o,n,A,u,t,h,o,r,i,t,y);
+    static const XMLCh AttributeIssuerEntityMatcher[] = UNICODE_LITERAL_28(A,t,t,r,i,b,u,t,e,I,s,s,u,e,r,E,n,t,i,t,y,M,a,t,c,h,e,r);
+    static const XMLCh AttributeRequesterEntityMatcher[] = UNICODE_LITERAL_31(A,t,t,r,i,b,u,t,e,R,e,q,u,e,s,t,e,r,E,n,t,i,t,y,M,a,t,c,h,e,r);
 };
 
+DECL_PUBLIC_QNAME(AnyMatchFunctor, ANY);
 DECL_BASIC_QNAME(AnyMatchFunctor, ANY);
+
+DECL_PUBLIC_QNAME(AndMatchFunctor, AND);
 DECL_BASIC_QNAME(AndMatchFunctor, AND);
+
+DECL_PUBLIC_QNAME(OrMatchFunctor, OR);
 DECL_BASIC_QNAME(OrMatchFunctor, OR);
+
+DECL_PUBLIC_QNAME(NotMatchFunctor, NOT);
 DECL_BASIC_QNAME(NotMatchFunctor, NOT);
+
+DECL_PUBLIC_QNAME(AttributeIssuerString, Issuer);
 DECL_BASIC_QNAME(AttributeIssuerString, AttributeIssuerString);
+
+DECL_PUBLIC_QNAME(AttributeRequesterString, Requester);
 DECL_BASIC_QNAME(AttributeRequesterString, AttributeRequesterString);
+
+DECL_PUBLIC_QNAME(AuthenticationMethodString, AuthenticationMethod);
 DECL_BASIC_QNAME(AuthenticationMethodString, AuthenticationMethodString);
+
+DECL_PUBLIC_QNAME(AttributeValueString, Value);
 DECL_BASIC_QNAME(AttributeValueString, AttributeValueString);
+
+DECL_PUBLIC_QNAME(AttributeScopeString, Scope);
 DECL_BASIC_QNAME(AttributeScopeString, AttributeScopeString);
+
+DECL_PUBLIC_QNAME(AttributeIssuerRegex, IssuerRegex);
 DECL_BASIC_QNAME(AttributeIssuerRegex, AttributeIssuerRegex);
+
+DECL_PUBLIC_QNAME(AttributeRequesterRegex, RequesterRegex);
 DECL_BASIC_QNAME(AttributeRequesterRegex, AttributeRequesterRegex);
+
+DECL_PUBLIC_QNAME(AuthenticationMethodRegex, AuthenticationMethodRegex);
 DECL_BASIC_QNAME(AuthenticationMethodRegex, AuthenticationMethodRegex);
+
+DECL_PUBLIC_QNAME(AttributeValueRegex, ValueRegex);
 DECL_BASIC_QNAME(AttributeValueRegex, AttributeValueRegex);
+
+DECL_PUBLIC_QNAME(AttributeScopeRegex, ScopeRegex);
 DECL_BASIC_QNAME(AttributeScopeRegex, AttributeScopeRegex);
+
+DECL_PUBLIC_QNAME(NumberOfAttributeValues, NumberOfAttributeValues);
 DECL_BASIC_QNAME(NumberOfAttributeValues, NumberOfAttributeValues);
-DECL_SAML_QNAME(AttributeIssuerInEntityGroup, AttributeIssuerInEntityGroup);
-DECL_SAML_QNAME(AttributeRequesterInEntityGroup, AttributeRequesterInEntityGroup);
-DECL_SAML_QNAME(InEntityGroup, InEntityGroup);
+
+DECL_PUBLIC_QNAME(AttributeIssuerEntityAttributeExactMatch, IssuerEntityAttributeExactMatch);
 DECL_SAML_QNAME(AttributeIssuerEntityAttributeExactMatch, AttributeIssuerEntityAttributeExactMatch);
+
+DECL_PUBLIC_QNAME(AttributeRequesterEntityAttributeExactMatch, EntityAttributeExactMatch);
 DECL_SAML_QNAME(AttributeRequesterEntityAttributeExactMatch, AttributeRequesterEntityAttributeExactMatch);
 DECL_SAML_QNAME(EntityAttributeExactMatch, EntityAttributeExactMatch);
+
+DECL_PUBLIC_QNAME(AttributeIssuerEntityAttributeRegexMatch, IssuerEntityAttributeRegexMatch);
 DECL_SAML_QNAME(AttributeIssuerEntityAttributeRegexMatch, AttributeIssuerEntityAttributeRegexMatch);
+
+DECL_PUBLIC_QNAME(AttributeRequesterEntityAttributeRegexMatch, EntityAttributeRegexMatch);
 DECL_SAML_QNAME(AttributeRequesterEntityAttributeRegexMatch, AttributeRequesterEntityAttributeRegexMatch);
 DECL_SAML_QNAME(EntityAttributeRegexMatch, EntityAttributeRegexMatch);
-DECL_SAML_QNAME(AttributeIssuerEntityMatcher, AttributeIssuerEntityMatcher);
-DECL_SAML_QNAME(AttributeRequesterEntityMatcher, AttributeRequesterEntityMatcher);
+
+DECL_PUBLIC_QNAME(AttributeIssuerInEntityGroup, IssuerInEntityGroup);
+DECL_SAML_QNAME(AttributeIssuerInEntityGroup, AttributeIssuerInEntityGroup);
+
+DECL_PUBLIC_QNAME(AttributeRequesterInEntityGroup, InEntityGroup);
+DECL_SAML_QNAME(AttributeRequesterInEntityGroup, AttributeRequesterInEntityGroup);
+DECL_SAML_QNAME(InEntityGroup, InEntityGroup);
+
+DECL_PUBLIC_QNAME(AttributeIssuerRegistrationAuthority, IssuerRegistrationAuthority);
+DECL_SAML_QNAME(AttributeIssuerRegistrationAuthority, AttributeIssuerRegistrationAuthority);
+
+DECL_PUBLIC_QNAME(RegistrationAuthority, RegistrationAuthority);
+DECL_SAML_QNAME(RegistrationAuthority, RegistrationAuthority);
+
+DECL_PUBLIC_QNAME(AttributeScopeMatchesShibMDScope, ScopeMatchesShibMDScope);
 DECL_SAML_QNAME(AttributeScopeMatchesShibMDScope, AttributeScopeMatchesShibMDScope);
+
+DECL_PUBLIC_QNAME(AttributeValueMatchesShibMDScope, ValueMatchesShibMDScope);
 DECL_SAML_QNAME(AttributeValueMatchesShibMDScope, AttributeValueMatchesShibMDScope);
+
+DECL_PUBLIC_QNAME(NameIDQualifierString, NameIDQualifierString);
 DECL_SAML_QNAME(NameIDQualifierString, NameIDQualifierString);
-DECL_SAML_QNAME(AttributeIssuerRegistrationAuthority, AttributeIssuerRegistrationAuthority);
-DECL_SAML_QNAME(RegistrationAuthority, RegistrationAuthority);
+
+DECL_PUBLIC_QNAME(AttributeIssuerEntityMatcher, AttributeIssuerEntityMatcher);
+DECL_SAML_QNAME(AttributeIssuerEntityMatcher, AttributeIssuerEntityMatcher);
+
+DECL_PUBLIC_QNAME(AttributeRequesterEntityMatcher, AttributeRequesterEntityMatcher);
+DECL_SAML_QNAME(AttributeRequesterEntityMatcher, AttributeRequesterEntityMatcher);
 
 void SHIBSP_API shibsp::registerMatchFunctors()
 {
     PluginManager< MatchFunctor,xmltooling::QName,pair<const FilterPolicyContext*,const DOMElement*> >& mgr =
         SPConfig::getConfig().MatchFunctorManager;
+
     REGISTER_FACTORY(AnyMatchFunctor);
     REGISTER_FACTORY(AndMatchFunctor);
     REGISTER_FACTORY(OrMatchFunctor);
@@ -162,23 +259,23 @@ void SHIBSP_API shibsp::registerMatchFunctors()
     REGISTER_FACTORY(AttributeValueRegex);
     REGISTER_FACTORY(AttributeScopeRegex);
     REGISTER_FACTORY(NumberOfAttributeValues);
-    REGISTER_FACTORY(AttributeIssuerInEntityGroup);
-    REGISTER_FACTORY(AttributeRequesterInEntityGroup);
     REGISTER_FACTORY(AttributeIssuerEntityAttributeExactMatch);
     REGISTER_FACTORY(AttributeRequesterEntityAttributeExactMatch);
     REGISTER_FACTORY(AttributeIssuerEntityAttributeRegexMatch);
     REGISTER_FACTORY(AttributeRequesterEntityAttributeRegexMatch);
-    REGISTER_FACTORY(AttributeIssuerEntityMatcher);
-    REGISTER_FACTORY(AttributeRequesterEntityMatcher);
+    REGISTER_FACTORY(AttributeIssuerInEntityGroup);
+    REGISTER_FACTORY(AttributeRequesterInEntityGroup);
+    REGISTER_FACTORY(AttributeIssuerRegistrationAuthority);
+    REGISTER_FACTORY(RegistrationAuthority);
     REGISTER_FACTORY(AttributeScopeMatchesShibMDScope);
     REGISTER_FACTORY(AttributeValueMatchesShibMDScope);
     REGISTER_FACTORY(NameIDQualifierString);
-    REGISTER_FACTORY(AttributeIssuerRegistrationAuthority);
-    REGISTER_FACTORY(RegistrationAuthority);
+    REGISTER_FACTORY(AttributeIssuerEntityMatcher);
+    REGISTER_FACTORY(AttributeRequesterEntityMatcher);
 
-    mgr.registerFactory(EntityAttributeExactMatchType, AttributeRequesterEntityAttributeExactMatchFactory);
-    mgr.registerFactory(EntityAttributeRegexMatchType, AttributeRequesterEntityAttributeRegexMatchFactory);
-    mgr.registerFactory(InEntityGroupType, AttributeRequesterInEntityGroupFactory);
+    mgr.registerFactory(DeprecatedEntityAttributeExactMatchType, AttributeRequesterEntityAttributeExactMatchFactory);
+    mgr.registerFactory(DeprecatedEntityAttributeRegexMatchType, AttributeRequesterEntityAttributeRegexMatchFactory);
+    mgr.registerFactory(DeprecatedInEntityGroupType, AttributeRequesterInEntityGroupFactory);
 }
 
 MatchFunctor::MatchFunctor()
diff --git a/shibsp/attribute/filtering/impl/RegistrationAuthorityFunctor.cpp b/shibsp/attribute/filtering/impl/RegistrationAuthorityFunctor.cpp
index 734dc0b..e860e09 100644
--- a/shibsp/attribute/filtering/impl/RegistrationAuthorityFunctor.cpp
+++ b/shibsp/attribute/filtering/impl/RegistrationAuthorityFunctor.cpp
@@ -88,7 +88,7 @@ namespace shibsp {
 
             if (info) {
                 auto_ptr_char authority(info->getRegistrationAuthority());
-                return authority.get() &&  m_registrars.find(authority.get()) != m_registrars.end();
+                return authority.get() && m_registrars.find(authority.get()) != m_registrars.end();
             }
             return m_matchIfMetadataSilent;
         }

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list