[java-shib-attribute] branch main updated: JSATTR-31 Add protocolSupportEnumeration-based filter polic

Rod Widdowson rdw at steadingsoftware.com
Tue Apr 8 18:33:10 UTC 2025


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

rdw pushed a commit to branch main
in repository java-shib-attribute.

View the commit online:
http://git.shibboleth.net/view/?p=java-shib-attribute.git;a=commit;h=eec9988379788fda53545f3476e9888303be05ce

The following commit(s) were added to refs/heads/main by this push:
     new eec998837 JSATTR-31 Add protocolSupportEnumeration-based filter polic
eec998837 is described below

commit eec9988379788fda53545f3476e9888303be05ce
Author: Rod Widdowson <rdw at steadingsoftware.com>
AuthorDate: Tue Apr 8 19:30:34 2025 +0100

    JSATTR-31 Add protocolSupportEnumeration-based filter polic
    
    https://shibboleth.atlassian.net/browse/JSATTR-31
    
    Add the impementation for the base class plus 3 concrete versions
    (Issuer, Requester, ProxiedRequester).
    
    Plus tests
---
 .../impl/AbstractProtocolSupportPolicyRule.java    | 76 +++++++++++++++++++
 .../impl/IssuerEntityAttributeExactPolicyRule.java |  2 +-
 .../saml/impl/IssuerProtocolSupportPolicyRule.java | 25 +++++++
 .../ProxiedRequesterProtocolSupportPolicyRule.java | 25 +++++++
 .../impl/RequesterProtocolSupportPolicyRule.java   | 25 +++++++
 .../policyrule/saml/impl/BaseMetadataTests.java    | 18 +++++
 .../saml/impl/ProtocolSupportPolicyRuleTest.java   | 86 ++++++++++++++++++++++
 7 files changed, 256 insertions(+), 1 deletion(-)

diff --git a/shib-attribute-filter-impl/src/main/java/net/shibboleth/idp/attribute/filter/policyrule/saml/impl/AbstractProtocolSupportPolicyRule.java b/shib-attribute-filter-impl/src/main/java/net/shibboleth/idp/attribute/filter/policyrule/saml/impl/AbstractProtocolSupportPolicyRule.java
new file mode 100644
index 000000000..b1eae53a6
--- /dev/null
+++ b/shib-attribute-filter-impl/src/main/java/net/shibboleth/idp/attribute/filter/policyrule/saml/impl/AbstractProtocolSupportPolicyRule.java
@@ -0,0 +1,76 @@
+package net.shibboleth.idp.attribute.filter.policyrule.saml.impl;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.saml.saml2.metadata.RoleDescriptor;
+import org.slf4j.Logger;
+
+import net.shibboleth.idp.attribute.filter.context.AttributeFilterContext;
+import net.shibboleth.idp.attribute.filter.policyrule.impl.AbstractPolicyRule;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Base class for Policy Rules that check whether a particular protocol is available for the supplied role.
+ *
+ * <p>
+ * Given the {@link RoleDescriptor}, this class does the match.
+ * </p>
+ *
+ */
+public abstract class AbstractProtocolSupportPolicyRule extends AbstractPolicyRule {
+
+	@Nonnull
+	private final Logger log = LoggerFactory.getLogger(AbstractProtocolSupportPolicyRule.class);
+
+	/**  What we are checking against. */
+	@NonnullAfterInit private String protocol;
+
+	@Override
+	protected void doInitialize() throws ComponentInitializationException {
+		super.doInitialize();
+		if (protocol == null) {
+			log.error("{} protocol not set", getLogPrefix());
+			throw new ComponentInitializationException("Protocol not set in ProtocolSupportPolicyRule"); 
+		}
+	}
+
+	/** Get {@link #protocol}.
+	 * @return {@link #protocol}
+	 */
+	@Nonnull public String getProtocol() {
+		assert protocol != null;
+		return protocol;
+	}
+
+	/** Set {@link #protocol}.
+	 * @param what thing to set.
+	 */
+	public void setProtocol(@Nonnull String what) {
+		protocol = Constraint.isNotNull(what, "Supplier protocol was null");
+	}
+
+	@Override
+	public Tristate matches(@Nonnull final AttributeFilterContext filterContext) {
+		final RoleDescriptor role = getRoleDescriptor(filterContext);
+		if (role == null) {
+			return Tristate.FAIL;
+		}
+		if (role.getSupportedProtocols().contains(protocol)) {
+			return Tristate.TRUE;
+		}
+		return Tristate.FALSE;
+	}
+
+    /**
+     * Gets the {@link RoleDescriptor} we are interested in
+     *
+     * @param filterContext current filter request context
+     *
+     * @return the RoleDescriptr
+     */
+	@Nullable protected abstract RoleDescriptor getRoleDescriptor(@Nonnull final AttributeFilterContext filterContext);
+}
diff --git a/shib-attribute-filter-impl/src/main/java/net/shibboleth/idp/attribute/filter/policyrule/saml/impl/IssuerEntityAttributeExactPolicyRule.java b/shib-attribute-filter-impl/src/main/java/net/shibboleth/idp/attribute/filter/policyrule/saml/impl/IssuerEntityAttributeExactPolicyRule.java
index 2d71eaf0c..17a4697ba 100644
--- a/shib-attribute-filter-impl/src/main/java/net/shibboleth/idp/attribute/filter/policyrule/saml/impl/IssuerEntityAttributeExactPolicyRule.java
+++ b/shib-attribute-filter-impl/src/main/java/net/shibboleth/idp/attribute/filter/policyrule/saml/impl/IssuerEntityAttributeExactPolicyRule.java
@@ -23,7 +23,7 @@ import org.opensaml.saml.common.messaging.context.SAMLMetadataContext;
 import org.opensaml.saml.saml2.metadata.EntityDescriptor;
 
 /**
- * Matcher that checks, via an exact match, if the attribute issuer contains an entity attribute with a given value.
+ * Policy Rule that checks, via an exact match, if the attribute issuer contains an entity attribute with a given value.
  */
 public class IssuerEntityAttributeExactPolicyRule extends AbstractEntityAttributeExactPolicyRule {
 
diff --git a/shib-attribute-filter-impl/src/main/java/net/shibboleth/idp/attribute/filter/policyrule/saml/impl/IssuerProtocolSupportPolicyRule.java b/shib-attribute-filter-impl/src/main/java/net/shibboleth/idp/attribute/filter/policyrule/saml/impl/IssuerProtocolSupportPolicyRule.java
new file mode 100644
index 000000000..d07cde919
--- /dev/null
+++ b/shib-attribute-filter-impl/src/main/java/net/shibboleth/idp/attribute/filter/policyrule/saml/impl/IssuerProtocolSupportPolicyRule.java
@@ -0,0 +1,25 @@
+package net.shibboleth.idp.attribute.filter.policyrule.saml.impl;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.saml.common.messaging.context.SAMLMetadataContext;
+import org.opensaml.saml.saml2.metadata.RoleDescriptor;
+
+import net.shibboleth.idp.attribute.filter.context.AttributeFilterContext;
+
+/**
+ * Concrete implementation of a Policy Rule to match against the Issuer's role's supported protocols.
+ */
+public class IssuerProtocolSupportPolicyRule extends AbstractProtocolSupportPolicyRule {
+
+	@Override
+	@Nullable protected RoleDescriptor getRoleDescriptor(@Nonnull final AttributeFilterContext filterContext) {
+		final SAMLMetadataContext context = filterContext.getIssuerMetadataContext();
+		if (context == null) {
+			return null;
+		}
+		return context.getRoleDescriptor();
+	}
+
+}
diff --git a/shib-attribute-filter-impl/src/main/java/net/shibboleth/idp/attribute/filter/policyrule/saml/impl/ProxiedRequesterProtocolSupportPolicyRule.java b/shib-attribute-filter-impl/src/main/java/net/shibboleth/idp/attribute/filter/policyrule/saml/impl/ProxiedRequesterProtocolSupportPolicyRule.java
new file mode 100644
index 000000000..23cc55190
--- /dev/null
+++ b/shib-attribute-filter-impl/src/main/java/net/shibboleth/idp/attribute/filter/policyrule/saml/impl/ProxiedRequesterProtocolSupportPolicyRule.java
@@ -0,0 +1,25 @@
+package net.shibboleth.idp.attribute.filter.policyrule.saml.impl;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.saml.common.messaging.context.SAMLMetadataContext;
+import org.opensaml.saml.saml2.metadata.RoleDescriptor;
+
+import net.shibboleth.idp.attribute.filter.context.AttributeFilterContext;
+
+/**
+ * Concrete implementation of a Policy Rule to match against the Proxied Requestor's role's supported protocols.
+ */
+public class ProxiedRequesterProtocolSupportPolicyRule extends AbstractProtocolSupportPolicyRule {
+
+	@Override
+	@Nullable protected RoleDescriptor getRoleDescriptor(@Nonnull final AttributeFilterContext filterContext) {
+		final SAMLMetadataContext context = filterContext.getProxiedRequesterMetadataContext();
+		if (context == null) {
+			return null;
+		}
+		return context.getRoleDescriptor();
+	}
+
+}
diff --git a/shib-attribute-filter-impl/src/main/java/net/shibboleth/idp/attribute/filter/policyrule/saml/impl/RequesterProtocolSupportPolicyRule.java b/shib-attribute-filter-impl/src/main/java/net/shibboleth/idp/attribute/filter/policyrule/saml/impl/RequesterProtocolSupportPolicyRule.java
new file mode 100644
index 000000000..eefabfdf0
--- /dev/null
+++ b/shib-attribute-filter-impl/src/main/java/net/shibboleth/idp/attribute/filter/policyrule/saml/impl/RequesterProtocolSupportPolicyRule.java
@@ -0,0 +1,25 @@
+package net.shibboleth.idp.attribute.filter.policyrule.saml.impl;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.saml.common.messaging.context.SAMLMetadataContext;
+import org.opensaml.saml.saml2.metadata.RoleDescriptor;
+
+import net.shibboleth.idp.attribute.filter.context.AttributeFilterContext;
+
+/**
+ * Concrete implementation of a Policy Rule to match against the Requestor's role's supported protocols.
+ */
+public class RequesterProtocolSupportPolicyRule extends AbstractProtocolSupportPolicyRule {
+
+	@Override
+	@Nullable protected RoleDescriptor getRoleDescriptor(@Nonnull final AttributeFilterContext filterContext) {
+		final SAMLMetadataContext context = filterContext.getRequesterMetadataContext();
+		if (context == null) {
+			return null;
+		}
+		return context.getRoleDescriptor();
+	}
+
+}
diff --git a/shib-attribute-filter-impl/src/test/java/net/shibboleth/idp/attribute/filter/policyrule/saml/impl/BaseMetadataTests.java b/shib-attribute-filter-impl/src/test/java/net/shibboleth/idp/attribute/filter/policyrule/saml/impl/BaseMetadataTests.java
index feea81af9..1f4798ba4 100644
--- a/shib-attribute-filter-impl/src/test/java/net/shibboleth/idp/attribute/filter/policyrule/saml/impl/BaseMetadataTests.java
+++ b/shib-attribute-filter-impl/src/test/java/net/shibboleth/idp/attribute/filter/policyrule/saml/impl/BaseMetadataTests.java
@@ -126,4 +126,22 @@ public class BaseMetadataTests extends XMLObjectBaseTestCase {
         return filterContext;
     }
 
+    @Nonnull static protected AttributeFilterContext proxiedReqMetadataContext(EntityDescriptor sp, String principal) {
+
+        final AttributeFilterContext filterContext = new AttributeFilterContext();
+        final SAMLMetadataContext metadataContext = filterContext.ensureSubcontext(SAMLMetadataContext.class);
+        assert metadataContext != null;
+
+        metadataContext.setEntityDescriptor(sp);
+        if (sp != null) {
+            metadataContext.setRoleDescriptor(sp.getSPSSODescriptor("urn:oasis:names:tc:SAML:2.0:protocol"));
+            filterContext.setAttributeIssuerID(sp.getEntityID());
+        }
+
+        filterContext.setPrincipal(principal);
+        filterContext.setProxiedRequesterMetadataContextLookupStrategy(new ChildContextLookup<>(SAMLMetadataContext.class, false));
+        return filterContext;
+    }
+
+
 }
diff --git a/shib-attribute-filter-impl/src/test/java/net/shibboleth/idp/attribute/filter/policyrule/saml/impl/ProtocolSupportPolicyRuleTest.java b/shib-attribute-filter-impl/src/test/java/net/shibboleth/idp/attribute/filter/policyrule/saml/impl/ProtocolSupportPolicyRuleTest.java
new file mode 100644
index 000000000..cb49bc3b6
--- /dev/null
+++ b/shib-attribute-filter-impl/src/test/java/net/shibboleth/idp/attribute/filter/policyrule/saml/impl/ProtocolSupportPolicyRuleTest.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.idp.attribute.filter.policyrule.saml.impl;
+
+import static org.testng.Assert.assertEquals;
+
+import org.opensaml.saml.common.xml.SAMLConstants;
+import org.testng.annotations.Test;
+
+import net.shibboleth.idp.attribute.filter.PolicyRequirementRule.Tristate;
+import net.shibboleth.shared.component.ComponentInitializationException;
+
+/**
+ * Test for all the ProtocolSupport Policy Rules.
+ */
+ at SuppressWarnings("javadoc")
+public class ProtocolSupportPolicyRuleTest extends BaseMetadataTests {
+
+	private AbstractProtocolSupportPolicyRule protocolSupportPolicyRule(final AbstractProtocolSupportPolicyRule rule, 
+			                          final String protocol) throws ComponentInitializationException {
+		rule.setId(protocol);
+		rule.setProtocol(protocol);
+		rule.initialize();
+		return rule;
+	}
+
+    @Test public void issuer() throws ComponentInitializationException {
+        AbstractProtocolSupportPolicyRule rule = protocolSupportPolicyRule(
+                new IssuerProtocolSupportPolicyRule(),
+                SAMLConstants.SAML20P_NS);
+
+        assertEquals(rule.matches(issMetadataContext(idpEntity, "Principal")), Tristate.TRUE);
+
+        assertEquals(rule.matches(reqMetadataContext(jiraEntity, "Principal")), Tristate.FAIL);
+
+        rule = protocolSupportPolicyRule(
+				new IssuerProtocolSupportPolicyRule(),
+				"SomeCrazyProtocol");
+        assertEquals(rule.matches(issMetadataContext(idpEntity, "Principal")), Tristate.FALSE);
+    }
+
+    @Test public void requester() throws ComponentInitializationException {
+        AbstractProtocolSupportPolicyRule rule = protocolSupportPolicyRule(
+                new RequesterProtocolSupportPolicyRule(),
+                SAMLConstants.SAML20P_NS);
+
+        assertEquals(rule.matches(issMetadataContext(idpEntity, "Principal")), Tristate.FAIL);
+
+        assertEquals(rule.matches(reqMetadataContext(jiraEntity, "Principal")), Tristate.TRUE);
+
+        rule = protocolSupportPolicyRule(
+                new RequesterProtocolSupportPolicyRule(),
+                "SomeCrazyProtocol");
+
+        assertEquals(rule.matches(reqMetadataContext(jiraEntity, "Principal")), Tristate.FALSE);
+    }
+
+    @Test public void proxiedRequester() throws ComponentInitializationException {
+        AbstractProtocolSupportPolicyRule rule = protocolSupportPolicyRule(
+                new ProxiedRequesterProtocolSupportPolicyRule(),
+                SAMLConstants.SAML20P_NS);
+
+        assertEquals(rule.matches(issMetadataContext(idpEntity, "Principal")), Tristate.FAIL);
+
+        assertEquals(rule.matches(proxiedReqMetadataContext(jiraEntity, "Principal")), Tristate.TRUE);
+
+        rule = protocolSupportPolicyRule(
+				new ProxiedRequesterProtocolSupportPolicyRule(),
+				"SomeCrazyProtocol");
+
+        assertEquals(rule.matches(proxiedReqMetadataContext(jiraEntity, "Principal")), Tristate.FALSE);
+
+    }
+}

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


More information about the commits mailing list