[java-identity-provider] branch master updated: IDP-1229 - Add Scoping/RequesterID chains into various IdP features
Scott Cantor
cantor.2 at osu.edu
Wed Nov 1 17:49:08 EDT 2017
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch master
in repository java-identity-provider.
View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=266a820401d762b5a20d0b8bd52324abac15c0cb
The following commit(s) were added to refs/heads/master by this push:
new 266a820 IDP-1229 - Add Scoping/RequesterID chains into various IdP features
266a820 is described below
commit 266a820401d762b5a20d0b8bd52324abac15c0cb
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Wed Nov 1 17:49:05 2017 -0400
IDP-1229 - Add Scoping/RequesterID chains into various IdP features
https://issues.shibboleth.net/jira/browse/IDP-1229
Attribute filtering support
---
.../filter/context/AttributeFilterContext.java | 67 ++++++++++++--
.../impl/ProxiedRequesterPolicyRule.java | 68 ++++++++++++++
.../impl/ProxiedRequesterRegexpPolicyRule.java | 64 +++++++++++++
.../impl/ProxiedRequesterPolicyRuleTest.java | 102 +++++++++++++++++++++
.../impl/ProxiedRequesterRegexpPolicyRuleTest.java | 81 ++++++++++++++++
.../impl/AttributeFilterNamespaceHandler.java | 7 ++
.../impl/ProxiedRequesterRegexRuleParser.java | 44 +++++++++
.../impl/ProxiedRequesterRuleParser.java | 44 +++++++++
.../ProxiedRequesterRegexRuleParserTest.java | 36 ++++++++
.../policy/ProxiedRequesterRuleParserTest.java | 95 +++++++++++++++++++
.../filter/matcher/afp/proxiedRequester.xml | 4 +
.../policyrule/afp/proxiedRegexRequester.xml | 4 +
.../filter/policyrule/afp/proxiedRequester.xml | 4 +
.../idp/profile/impl/FilterAttributes.java | 58 +++++++++---
.../src/main/resources/schema/shibboleth-afp.xsd | 22 +++++
15 files changed, 680 insertions(+), 20 deletions(-)
diff --git a/idp-attribute-filter-api/src/main/java/net/shibboleth/idp/attribute/filter/context/AttributeFilterContext.java b/idp-attribute-filter-api/src/main/java/net/shibboleth/idp/attribute/filter/context/AttributeFilterContext.java
index 638ee3e..8b1447d 100644
--- a/idp-attribute-filter-api/src/main/java/net/shibboleth/idp/attribute/filter/context/AttributeFilterContext.java
+++ b/idp-attribute-filter-api/src/main/java/net/shibboleth/idp/attribute/filter/context/AttributeFilterContext.java
@@ -34,6 +34,7 @@ import net.shibboleth.utilities.java.support.collection.CollectionSupport;
import net.shibboleth.utilities.java.support.logic.Constraint;
import org.opensaml.messaging.context.BaseContext;
+import org.opensaml.profile.context.ProxiedRequesterContext;
import org.opensaml.saml.common.messaging.context.SAMLMetadataContext;
import org.opensaml.saml.metadata.resolver.MetadataResolver;
@@ -68,10 +69,17 @@ public final class AttributeFilterContext extends BaseContext {
/** Cache of the metadata context. */
@Nullable private SAMLMetadataContext requesterMetadataContext;
+ /** Cache of the proxied requester context. */
+ @Nullable private ProxiedRequesterContext proxiedRequesterContext;
+
/** Lookup strategy used to locate the SP's metadata context. */
- @NonnullAfterInit
+ @Nullable
private Function<AttributeFilterContext,SAMLMetadataContext> requesterMetadataContextLookupStrategy;
+ /** Lookup strategy used to locate a {@link ProxiedRequesterContext}. */
+ @Nullable
+ private Function<AttributeFilterContext,ProxiedRequesterContext> proxiedRequesterContextLookupStrategy;
+
/** Constructor. */
public AttributeFilterContext() {
prefilteredAttributes = new HashMap<String, IdPAttribute>();
@@ -225,26 +233,54 @@ public final class AttributeFilterContext extends BaseContext {
/**
* Get the strategy used to locate the SP's metadata context.
*
- * @return Returns the requesterMetadataContextLookupStrategy.
+ * @return lookup strategy
*/
- @NonnullAfterInit public Function<AttributeFilterContext, SAMLMetadataContext>
- getRequesterMetadataContextLookupStrategy() {
+ @NonnullAfterInit
+ public Function<AttributeFilterContext, SAMLMetadataContext> getRequesterMetadataContextLookupStrategy() {
return requesterMetadataContextLookupStrategy;
}
/**
* Set the strategy used to locate the SP's metadata context.
*
- * @param strategy The requesterMetadataContextLookupStrategy to set.
+ * @param strategy lookup strategy
*/
public void setRequesterMetadataContextLookupStrategy(
- @Nonnull final Function<AttributeFilterContext, SAMLMetadataContext> strategy) {
+ @Nonnull final Function<AttributeFilterContext,SAMLMetadataContext> strategy) {
requesterMetadataContextLookupStrategy =
Constraint.isNotNull(strategy, "MetadataContext lookup strategy cannot be null");
}
- /** Get the Requester Metadata context.<br/> This value is cached and so only calculated once.
- * @return the cached context
+ /**
+ * Get the strategy used to locate the {@link ProxiedRequesterContext}.
+ *
+ * @return lookup strategy
+ *
+ * @since 3.4.0
+ */
+ @NonnullAfterInit
+ public Function<AttributeFilterContext,ProxiedRequesterContext> getProxiedRequesterContextLookupStrategy() {
+ return proxiedRequesterContextLookupStrategy;
+ }
+
+ /**
+ * Set the strategy used to locate the SP's metadata context.
+ *
+ * @param strategy lookup strategy
+ *
+ * @since 3.4.0
+ */
+ public void setProxiedRequesterContextLookupStrategy(
+ @Nonnull final Function<AttributeFilterContext,ProxiedRequesterContext> strategy) {
+ proxiedRequesterContextLookupStrategy =
+ Constraint.isNotNull(strategy, "ProxiedRequesterContext lookup strategy cannot be null");
+ }
+
+ /** Get the Requester Metadata context.
+ *
+ * <p>This value is cached and so only calculated once.</p>
+ *
+ * @return the context
*/
@Nullable public SAMLMetadataContext getRequesterMetadataContext() {
if (null == requesterMetadataContext && null != requesterMetadataContextLookupStrategy) {
@@ -253,4 +289,19 @@ public final class AttributeFilterContext extends BaseContext {
return requesterMetadataContext;
}
+ /** Get the {@link ProxiedRequesterContext}.
+ *
+ * <p>This value is cached and so only calculated once.</p>
+ *
+ * @return the context
+ *
+ * @since 3.4.0
+ */
+ @Nullable public ProxiedRequesterContext getProxiedRequesterContext() {
+ if (null == proxiedRequesterContext && null != proxiedRequesterContextLookupStrategy) {
+ proxiedRequesterContext = proxiedRequesterContextLookupStrategy.apply(this);
+ }
+ return proxiedRequesterContext;
+ }
+
}
\ No newline at end of file
diff --git a/idp-attribute-filter-impl/src/main/java/net/shibboleth/idp/attribute/filter/policyrule/filtercontext/impl/ProxiedRequesterPolicyRule.java b/idp-attribute-filter-impl/src/main/java/net/shibboleth/idp/attribute/filter/policyrule/filtercontext/impl/ProxiedRequesterPolicyRule.java
new file mode 100644
index 0000000..da7ada5
--- /dev/null
+++ b/idp-attribute-filter-impl/src/main/java/net/shibboleth/idp/attribute/filter/policyrule/filtercontext/impl/ProxiedRequesterPolicyRule.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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.filtercontext.impl;
+
+import javax.annotation.Nonnull;
+
+import net.shibboleth.idp.attribute.filter.context.AttributeFilterContext;
+import net.shibboleth.idp.attribute.filter.policyrule.impl.AbstractStringPolicyRule;
+import net.shibboleth.utilities.java.support.component.ComponentSupport;
+
+import org.opensaml.profile.context.ProxiedRequesterContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Compare a proxied attribute requester's entity ID for this resolution with the provided name.
+ *
+ * @since 3.4.0
+ */
+public class ProxiedRequesterPolicyRule extends AbstractStringPolicyRule {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(ProxiedRequesterPolicyRule.class);
+
+ /**
+ * Compare the requester from the context with the provided string.
+ *
+ * @param filterContext the context
+ * @return whether it matches
+ *
+ * {@inheritDoc}
+ */
+ @Override public Tristate matches(@Nonnull final AttributeFilterContext filterContext) {
+ ComponentSupport.ifNotInitializedThrowUninitializedComponentException(this);
+
+ final ProxiedRequesterContext ctx = filterContext.getProxiedRequesterContext();
+ if (null == ctx) {
+ return Tristate.FALSE;
+ }
+
+ if (isIgnoreCase()) {
+ for (final String requester : ctx.getRequesters()) {
+ if (stringCompare(requester) == Tristate.TRUE) {
+ return Tristate.TRUE;
+ }
+ }
+ return Tristate.FALSE;
+ } else {
+ return ctx.getRequesters().contains(getMatchString()) ? Tristate.TRUE : Tristate.FALSE;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/idp-attribute-filter-impl/src/main/java/net/shibboleth/idp/attribute/filter/policyrule/filtercontext/impl/ProxiedRequesterRegexpPolicyRule.java b/idp-attribute-filter-impl/src/main/java/net/shibboleth/idp/attribute/filter/policyrule/filtercontext/impl/ProxiedRequesterRegexpPolicyRule.java
new file mode 100644
index 0000000..63af1e9
--- /dev/null
+++ b/idp-attribute-filter-impl/src/main/java/net/shibboleth/idp/attribute/filter/policyrule/filtercontext/impl/ProxiedRequesterRegexpPolicyRule.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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.filtercontext.impl;
+
+import javax.annotation.Nonnull;
+
+import net.shibboleth.idp.attribute.filter.context.AttributeFilterContext;
+import net.shibboleth.idp.attribute.filter.policyrule.impl.AbstractRegexpPolicyRule;
+import net.shibboleth.utilities.java.support.component.ComponentSupport;
+
+import org.opensaml.profile.context.ProxiedRequesterContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Compare a proxied attribute requester's entity ID for this resolution with the provided regexp.
+ *
+ * @since 3.4.0
+ */
+public class ProxiedRequesterRegexpPolicyRule extends AbstractRegexpPolicyRule {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(ProxiedRequesterRegexpPolicyRule.class);
+
+ /**
+ * Compare the requester from the context with the provided regexp.
+ *
+ * @param filterContext the context
+ * @return whether it matches
+ *
+ * {@inheritDoc}
+ */
+ @Override public Tristate matches(@Nonnull final AttributeFilterContext filterContext) {
+ ComponentSupport.ifNotInitializedThrowUninitializedComponentException(this);
+
+ final ProxiedRequesterContext ctx = filterContext.getProxiedRequesterContext();
+ if (null == ctx) {
+ return Tristate.FALSE;
+ }
+
+ for (final String requester : ctx.getRequesters()) {
+ if (regexpCompare(requester) == Tristate.TRUE) {
+ return Tristate.TRUE;
+ }
+ }
+
+ return Tristate.FALSE;
+ }
+}
\ No newline at end of file
diff --git a/idp-attribute-filter-impl/src/test/java/net/shibboleth/idp/attribute/filter/policyrule/filtercontext/impl/ProxiedRequesterPolicyRuleTest.java b/idp-attribute-filter-impl/src/test/java/net/shibboleth/idp/attribute/filter/policyrule/filtercontext/impl/ProxiedRequesterPolicyRuleTest.java
new file mode 100644
index 0000000..a1fcc71
--- /dev/null
+++ b/idp-attribute-filter-impl/src/test/java/net/shibboleth/idp/attribute/filter/policyrule/filtercontext/impl/ProxiedRequesterPolicyRuleTest.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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.filtercontext.impl;
+
+import net.shibboleth.idp.attribute.filter.PolicyRequirementRule.Tristate;
+import net.shibboleth.idp.attribute.filter.context.AttributeFilterContext;
+import net.shibboleth.idp.attribute.filter.matcher.impl.DataSources;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.utilities.java.support.component.UninitializedComponentException;
+
+import java.util.Arrays;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.context.ProxiedRequesterContext;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * Tests for {@link ProxiedRequesterPolicyRule}.
+ */
+public class ProxiedRequesterPolicyRuleTest {
+
+ private ProxiedRequesterPolicyRule getMatcher(boolean caseSensitive) throws ComponentInitializationException {
+ final ProxiedRequesterPolicyRule matcher = new ProxiedRequesterPolicyRule();
+ matcher.setMatchString("requester");
+ matcher.setIgnoreCase(!caseSensitive);
+ matcher.setId("Test");
+ matcher.initialize();
+ return matcher;
+
+ }
+
+ private ProxiedRequesterPolicyRule getMatcher() throws ComponentInitializationException {
+ return getMatcher(true);
+ }
+
+ @Test public void testNull() throws ComponentInitializationException {
+
+ try {
+ new ProxiedRequesterPolicyRule().matches(null);
+ Assert.fail();
+ } catch (UninitializedComponentException ex) {
+ // OK
+ }
+ }
+
+ @Test public void testUnpopulated()
+ throws ComponentInitializationException {
+ Assert.assertEquals(getMatcher().matches(DataSources.unPopulatedFilterContext()), Tristate.FALSE);
+ }
+
+ @Test public void testNoProxies()
+ throws ComponentInitializationException {
+ Assert.assertEquals(getMatcher().matches(DataSources.populatedFilterContext(null, null, "foo")), Tristate.FALSE);
+ }
+
+ @Test public void testCaseSensitive() throws ComponentInitializationException {
+
+ final ProxiedRequesterPolicyRule matcher = getMatcher();
+
+ final AttributeFilterContext ctx = DataSources.populatedFilterContext(null, null, "wibble");
+ ctx.setProxiedRequesterContextLookupStrategy(
+ new ChildContextLookup<AttributeFilterContext,ProxiedRequesterContext>(ProxiedRequesterContext.class));
+ ctx.getSubcontext(ProxiedRequesterContext.class, true).getRequesters().addAll(Arrays.asList("foo", "bar"));
+
+ Assert.assertEquals(matcher.matches(ctx), Tristate.FALSE);
+
+ ctx.getSubcontext(ProxiedRequesterContext.class).getRequesters().add("requester");
+ Assert.assertEquals(matcher.matches(ctx), Tristate.TRUE);
+ }
+
+ @Test public void testCaseInsensitive() throws ComponentInitializationException {
+
+ final ProxiedRequesterPolicyRule matcher = getMatcher(false);
+
+ final AttributeFilterContext ctx = DataSources.populatedFilterContext(null, null, "wibble");
+ ctx.setProxiedRequesterContextLookupStrategy(
+ new ChildContextLookup<AttributeFilterContext,ProxiedRequesterContext>(ProxiedRequesterContext.class));
+ ctx.getSubcontext(ProxiedRequesterContext.class, true).getRequesters().addAll(Arrays.asList("foo", "bar"));
+
+ Assert.assertEquals(matcher.matches(ctx), Tristate.FALSE);
+
+ ctx.getSubcontext(ProxiedRequesterContext.class).getRequesters().add("REQUESTER");
+ Assert.assertEquals(matcher.matches(ctx), Tristate.TRUE);
+ }
+
+}
\ No newline at end of file
diff --git a/idp-attribute-filter-impl/src/test/java/net/shibboleth/idp/attribute/filter/policyrule/filtercontext/impl/ProxiedRequesterRegexpPolicyRuleTest.java b/idp-attribute-filter-impl/src/test/java/net/shibboleth/idp/attribute/filter/policyrule/filtercontext/impl/ProxiedRequesterRegexpPolicyRuleTest.java
new file mode 100644
index 0000000..aad7249
--- /dev/null
+++ b/idp-attribute-filter-impl/src/test/java/net/shibboleth/idp/attribute/filter/policyrule/filtercontext/impl/ProxiedRequesterRegexpPolicyRuleTest.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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.filtercontext.impl;
+
+import net.shibboleth.idp.attribute.filter.PolicyRequirementRule.Tristate;
+import net.shibboleth.idp.attribute.filter.context.AttributeFilterContext;
+import net.shibboleth.idp.attribute.filter.matcher.impl.DataSources;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.utilities.java.support.component.UninitializedComponentException;
+
+import java.util.Arrays;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.context.ProxiedRequesterContext;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * Tests for {@link ProxiedRequesterRegexpPolicyRule}.
+ */
+public class ProxiedRequesterRegexpPolicyRuleTest {
+
+ private ProxiedRequesterRegexpPolicyRule getMatcher() throws ComponentInitializationException {
+ final ProxiedRequesterRegexpPolicyRule matcher = new ProxiedRequesterRegexpPolicyRule();
+ matcher.setRegularExpression("^requ.*");
+ matcher.setId("Test");
+ matcher.initialize();
+ return matcher;
+ }
+
+ @Test public void testNull() throws ComponentInitializationException {
+
+ try {
+ new ProxiedRequesterRegexpPolicyRule().matches(null);
+ Assert.fail();
+ } catch (UninitializedComponentException ex) {
+ // OK
+ }
+ }
+
+ @Test public void testUnpopulated()
+ throws ComponentInitializationException {
+ Assert.assertEquals(getMatcher().matches(DataSources.unPopulatedFilterContext()), Tristate.FALSE);
+ }
+
+ @Test public void testNoRequester()
+ throws ComponentInitializationException {
+ Assert.assertEquals(getMatcher().matches(DataSources.populatedFilterContext(null, null, "foo")), Tristate.FALSE);
+ }
+
+ @Test public void testAll() throws ComponentInitializationException {
+
+ final ProxiedRequesterRegexpPolicyRule matcher = getMatcher();
+
+ final AttributeFilterContext ctx = DataSources.populatedFilterContext(null, null, "wibble");
+ ctx.setProxiedRequesterContextLookupStrategy(
+ new ChildContextLookup<AttributeFilterContext,ProxiedRequesterContext>(ProxiedRequesterContext.class));
+ ctx.getSubcontext(ProxiedRequesterContext.class, true).getRequesters().addAll(Arrays.asList("foo", "bar"));
+
+ Assert.assertEquals(matcher.matches(ctx), Tristate.FALSE);
+
+ ctx.getSubcontext(ProxiedRequesterContext.class).getRequesters().add("requester");
+ Assert.assertEquals(matcher.matches(ctx), Tristate.TRUE);
+ }
+
+}
\ No newline at end of file
diff --git a/idp-attribute-filter-spring/src/main/java/net/shibboleth/idp/attribute/filter/spring/impl/AttributeFilterNamespaceHandler.java b/idp-attribute-filter-spring/src/main/java/net/shibboleth/idp/attribute/filter/spring/impl/AttributeFilterNamespaceHandler.java
index 8e1e46b..945d682 100644
--- a/idp-attribute-filter-spring/src/main/java/net/shibboleth/idp/attribute/filter/spring/impl/AttributeFilterNamespaceHandler.java
+++ b/idp-attribute-filter-spring/src/main/java/net/shibboleth/idp/attribute/filter/spring/impl/AttributeFilterNamespaceHandler.java
@@ -38,6 +38,8 @@ import net.shibboleth.idp.attribute.filter.spring.policyrule.impl.NumOfAttribute
import net.shibboleth.idp.attribute.filter.spring.policyrule.impl.PredicateRuleParser;
import net.shibboleth.idp.attribute.filter.spring.policyrule.impl.PrincipalNameRegexRuleParser;
import net.shibboleth.idp.attribute.filter.spring.policyrule.impl.PrincipalNameRuleParser;
+import net.shibboleth.idp.attribute.filter.spring.policyrule.impl.ProxiedRequesterRegexRuleParser;
+import net.shibboleth.idp.attribute.filter.spring.policyrule.impl.ProxiedRequesterRuleParser;
import net.shibboleth.idp.attribute.filter.spring.saml.impl.AttributeInMetadataRuleParser;
import net.shibboleth.idp.attribute.filter.spring.saml.impl.AttributeRequesterEntityAttributeExactRuleParser;
import net.shibboleth.idp.attribute.filter.spring.saml.impl.AttributeRequesterEntityAttributeRegexRuleParser;
@@ -96,6 +98,11 @@ public class AttributeFilterNamespaceHandler extends BaseSpringNamespaceHandler
registerBeanDefinitionParser(AttributeRequesterRegexRuleParser.SCHEMA_TYPE_AFP,
new AttributeRequesterRegexRuleParser());
+ registerBeanDefinitionParser(ProxiedRequesterRuleParser.SCHEMA_TYPE_AFP, new ProxiedRequesterRuleParser());
+
+ registerBeanDefinitionParser(ProxiedRequesterRegexRuleParser.SCHEMA_TYPE_AFP,
+ new ProxiedRequesterRegexRuleParser());
+
registerBeanDefinitionParser(AttributeIssuerRuleParser.SCHEMA_TYPE_AFP, new AttributeIssuerRuleParser());
registerBeanDefinitionParser(AttributeIssuerRegexRuleParser.SCHEMA_TYPE_AFP,
diff --git a/idp-attribute-filter-spring/src/main/java/net/shibboleth/idp/attribute/filter/spring/policyrule/impl/ProxiedRequesterRegexRuleParser.java b/idp-attribute-filter-spring/src/main/java/net/shibboleth/idp/attribute/filter/spring/policyrule/impl/ProxiedRequesterRegexRuleParser.java
new file mode 100644
index 0000000..8bac980
--- /dev/null
+++ b/idp-attribute-filter-spring/src/main/java/net/shibboleth/idp/attribute/filter/spring/policyrule/impl/ProxiedRequesterRegexRuleParser.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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.spring.policyrule.impl;
+
+import javax.annotation.Nonnull;
+import javax.xml.namespace.QName;
+
+import net.shibboleth.idp.attribute.filter.policyrule.filtercontext.impl.ProxiedRequesterRegexpPolicyRule;
+import net.shibboleth.idp.attribute.filter.spring.BaseFilterParser;
+
+/**
+ * Bean definition parser for {@link ProxiedRequesterRegexpPolicyRule}.
+ */
+public class ProxiedRequesterRegexRuleParser extends AbstractRegexPolicyRuleParser {
+
+ /** Schema type. */
+ @Nonnull public static final QName SCHEMA_TYPE_AFP = new QName(BaseFilterParser.NAMESPACE, "ProxiedRequesterRegex");
+
+ /** {@inheritDoc} */
+ @Override protected QName getAFPName() {
+ return SCHEMA_TYPE_AFP;
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nonnull protected Class<ProxiedRequesterRegexpPolicyRule> getNativeBeanClass() {
+ return ProxiedRequesterRegexpPolicyRule.class;
+ }
+
+}
\ No newline at end of file
diff --git a/idp-attribute-filter-spring/src/main/java/net/shibboleth/idp/attribute/filter/spring/policyrule/impl/ProxiedRequesterRuleParser.java b/idp-attribute-filter-spring/src/main/java/net/shibboleth/idp/attribute/filter/spring/policyrule/impl/ProxiedRequesterRuleParser.java
new file mode 100644
index 0000000..cbd1942
--- /dev/null
+++ b/idp-attribute-filter-spring/src/main/java/net/shibboleth/idp/attribute/filter/spring/policyrule/impl/ProxiedRequesterRuleParser.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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.spring.policyrule.impl;
+
+import javax.annotation.Nonnull;
+import javax.xml.namespace.QName;
+
+import net.shibboleth.idp.attribute.filter.policyrule.filtercontext.impl.ProxiedRequesterPolicyRule;
+import net.shibboleth.idp.attribute.filter.spring.BaseFilterParser;
+
+/**
+ * Bean definition parser for {@link ProxiedRequesterPolicyRule}.
+ */
+public class ProxiedRequesterRuleParser extends AbstractStringPolicyRuleParser {
+
+ /** Schema type. */
+ @Nonnull public static final QName SCHEMA_TYPE_AFP = new QName(BaseFilterParser.NAMESPACE, "ProxiedRequester");
+
+ /** {@inheritDoc} */
+ @Override protected QName getAFPName() {
+ return SCHEMA_TYPE_AFP;
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nonnull protected Class<ProxiedRequesterPolicyRule> getNativeBeanClass() {
+ return ProxiedRequesterPolicyRule.class;
+ }
+
+}
\ No newline at end of file
diff --git a/idp-attribute-filter-spring/src/test/java/net/shibboleth/idp/attribute/filter/spring/policy/ProxiedRequesterRegexRuleParserTest.java b/idp-attribute-filter-spring/src/test/java/net/shibboleth/idp/attribute/filter/spring/policy/ProxiedRequesterRegexRuleParserTest.java
new file mode 100644
index 0000000..ace4e5b
--- /dev/null
+++ b/idp-attribute-filter-spring/src/test/java/net/shibboleth/idp/attribute/filter/spring/policy/ProxiedRequesterRegexRuleParserTest.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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.spring.policy;
+
+import net.shibboleth.idp.attribute.filter.policyrule.filtercontext.impl.ProxiedRequesterRegexpPolicyRule;
+import net.shibboleth.idp.attribute.filter.spring.BaseAttributeFilterParserTest;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class ProxiedRequesterRegexRuleParserTest extends BaseAttributeFilterParserTest {
+
+
+ @Test public void policy() throws ComponentInitializationException {
+
+ final ProxiedRequesterRegexpPolicyRule arRule = (ProxiedRequesterRegexpPolicyRule) getPolicyRule("proxiedRegexRequester.xml", true);
+ Assert.assertEquals(arRule.getRegularExpression(), "^urn:example:.*$");
+ }
+
+}
\ No newline at end of file
diff --git a/idp-attribute-filter-spring/src/test/java/net/shibboleth/idp/attribute/filter/spring/policy/ProxiedRequesterRuleParserTest.java b/idp-attribute-filter-spring/src/test/java/net/shibboleth/idp/attribute/filter/spring/policy/ProxiedRequesterRuleParserTest.java
new file mode 100644
index 0000000..f0d5026
--- /dev/null
+++ b/idp-attribute-filter-spring/src/test/java/net/shibboleth/idp/attribute/filter/spring/policy/ProxiedRequesterRuleParserTest.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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.spring.policy;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Set;
+
+import net.shibboleth.idp.attribute.IdPAttribute;
+import net.shibboleth.idp.attribute.IdPAttributeValue;
+import net.shibboleth.idp.attribute.filter.Matcher;
+import net.shibboleth.idp.attribute.filter.PolicyRequirementRule;
+import net.shibboleth.idp.attribute.filter.PolicyRequirementRule.Tristate;
+import net.shibboleth.idp.attribute.filter.context.AttributeFilterContext;
+import net.shibboleth.idp.attribute.filter.matcher.impl.DataSources;
+import net.shibboleth.idp.attribute.filter.policyrule.filtercontext.impl.ProxiedRequesterPolicyRule;
+import net.shibboleth.idp.attribute.filter.spring.BaseAttributeFilterParserTest;
+import net.shibboleth.idp.attribute.resolver.ResolutionException;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.context.ProxiedRequesterContext;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class ProxiedRequesterRuleParserTest extends BaseAttributeFilterParserTest {
+
+ private Map<String, IdPAttribute> epaUid;
+
+ @BeforeClass public void setupAttributes() throws ComponentInitializationException, ResolutionException {
+
+ epaUid = getAttributes("epa-uid.xml");
+ }
+
+ @Test public void policy() throws ComponentInitializationException {
+ policy("proxiedRequester.xml", true);
+ }
+
+ public void policy(String path, boolean isAfp) throws ComponentInitializationException {
+ final PolicyRequirementRule rule = getPolicyRule(path, isAfp);
+
+ AttributeFilterContext filterContext = DataSources.populatedFilterContext("principal", "issuer", "http://example.org");
+ filterContext.setProxiedRequesterContextLookupStrategy(
+ new ChildContextLookup<AttributeFilterContext,ProxiedRequesterContext>(ProxiedRequesterContext.class));
+ filterContext.getSubcontext(ProxiedRequesterContext.class, true).getRequesters().addAll(Arrays.asList("foo", "bar"));
+
+
+ Assert.assertEquals(rule.matches(filterContext), Tristate.FALSE);
+ filterContext.getSubcontext(ProxiedRequesterContext.class).getRequesters().add("https://service.example.edu/shibboleth-sp");
+ Assert.assertEquals(rule.matches(filterContext), Tristate.TRUE);
+
+ final ProxiedRequesterPolicyRule arRule = (ProxiedRequesterPolicyRule) rule;
+ Assert.assertEquals(arRule.getMatchString(), "https://service.example.edu/shibboleth-sp");
+ Assert.assertFalse(arRule.isIgnoreCase());
+ }
+
+ @Test public void matcher() throws ComponentInitializationException {
+ matcher("proxiedRequester.xml", true);
+ }
+
+ public void matcher(String path, boolean isAfp) throws ComponentInitializationException {
+ final Matcher matcher = getMatcher(path, isAfp);
+
+ AttributeFilterContext filterContext = DataSources.populatedFilterContext("principal", "issuer", "http://example.org");
+ filterContext.setProxiedRequesterContextLookupStrategy(
+ new ChildContextLookup<AttributeFilterContext,ProxiedRequesterContext>(ProxiedRequesterContext.class));
+ filterContext.getSubcontext(ProxiedRequesterContext.class, true).getRequesters().addAll(Arrays.asList("foo", "bar"));
+
+ filterContext.setPrefilteredIdPAttributes(epaUid.values());
+ Set<IdPAttributeValue<?>> result = matcher.getMatchingValues(epaUid.get("uid"), filterContext);
+ Assert.assertTrue(result.isEmpty());
+
+ filterContext.getSubcontext(ProxiedRequesterContext.class).getRequesters().add("https://service.example.edu/shibboleth-sp");
+ result = matcher.getMatchingValues(epaUid.get("uid"), filterContext);
+ Assert.assertEquals(result.size(), 1);
+ Assert.assertEquals(result.iterator().next().getValue(), "daffyDuck");
+ }
+
+}
\ No newline at end of file
diff --git a/idp-attribute-filter-spring/src/test/resources/net/shibboleth/idp/attribute/filter/matcher/afp/proxiedRequester.xml b/idp-attribute-filter-spring/src/test/resources/net/shibboleth/idp/attribute/filter/matcher/afp/proxiedRequester.xml
new file mode 100644
index 0000000..2c55d14
--- /dev/null
+++ b/idp-attribute-filter-spring/src/test/resources/net/shibboleth/idp/attribute/filter/matcher/afp/proxiedRequester.xml
@@ -0,0 +1,4 @@
+<AttributeRule attributeID="email" xmlns="urn:mace:shibboleth:2.0:afp" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:afp http://shibboleth.net/schema/idp/shibboleth-afp.xsd">
+ <PermitValueRule xsi:type="ProxiedRequester" value="https://service.example.edu/shibboleth-sp" />
+</AttributeRule>
\ No newline at end of file
diff --git a/idp-attribute-filter-spring/src/test/resources/net/shibboleth/idp/attribute/filter/policyrule/afp/proxiedRegexRequester.xml b/idp-attribute-filter-spring/src/test/resources/net/shibboleth/idp/attribute/filter/policyrule/afp/proxiedRegexRequester.xml
new file mode 100644
index 0000000..c4d681b
--- /dev/null
+++ b/idp-attribute-filter-spring/src/test/resources/net/shibboleth/idp/attribute/filter/policyrule/afp/proxiedRegexRequester.xml
@@ -0,0 +1,4 @@
+<AttributeFilterPolicy id="MostBasicExample" xmlns="urn:mace:shibboleth:2.0:afp" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:afp http://shibboleth.net/schema/idp/shibboleth-afp.xsd">
+ <PolicyRequirementRule xsi:type="ProxiedRequesterRegex" regex="^urn:example:.*$" />
+</AttributeFilterPolicy>
diff --git a/idp-attribute-filter-spring/src/test/resources/net/shibboleth/idp/attribute/filter/policyrule/afp/proxiedRequester.xml b/idp-attribute-filter-spring/src/test/resources/net/shibboleth/idp/attribute/filter/policyrule/afp/proxiedRequester.xml
new file mode 100644
index 0000000..03b4392
--- /dev/null
+++ b/idp-attribute-filter-spring/src/test/resources/net/shibboleth/idp/attribute/filter/policyrule/afp/proxiedRequester.xml
@@ -0,0 +1,4 @@
+<AttributeFilterPolicy id="MostBasicExample" xmlns="urn:mace:shibboleth:2.0:afp" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:afp http://shibboleth.net/schema/idp/shibboleth-afp.xsd" >
+ <PolicyRequirementRule xsi:type="ProxiedRequester" value="https://service.example.edu/shibboleth-sp" ignoreCase="false" />
+</AttributeFilterPolicy>
diff --git a/idp-profile-impl/src/main/java/net/shibboleth/idp/profile/impl/FilterAttributes.java b/idp-profile-impl/src/main/java/net/shibboleth/idp/profile/impl/FilterAttributes.java
index 200b98c..3f64f34 100644
--- a/idp-profile-impl/src/main/java/net/shibboleth/idp/profile/impl/FilterAttributes.java
+++ b/idp-profile-impl/src/main/java/net/shibboleth/idp/profile/impl/FilterAttributes.java
@@ -42,6 +42,7 @@ import org.opensaml.messaging.context.navigate.ChildContextLookup;
import org.opensaml.messaging.context.navigate.RootContextLookup;
import org.opensaml.profile.action.ActionSupport;
import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.profile.context.ProxiedRequesterContext;
import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
import org.opensaml.saml.common.messaging.context.SAMLMetadataContext;
import org.opensaml.saml.common.messaging.context.SAMLPeerEntityContext;
@@ -101,6 +102,18 @@ public class FilterAttributes extends AbstractProfileAction {
* Strategy used to locate the {@link SAMLMetadataContext} associated with a given {@link AttributeFilterContext}.
*/
@Nonnull private Function<AttributeFilterContext,SAMLMetadataContext> metadataFromFilterLookupStrategy;
+
+ /**
+ * Strategy used to locate the {@link ProxiedRequesterContext} associated with a given
+ * {@link ProfileRequestContext}.
+ */
+ @Nonnull private Function<ProfileRequestContext,ProxiedRequesterContext> proxiedRequesterContextLookupStrategy;
+
+ /**
+ * Strategy used to locate the {@link ProxiedRequesterContext} associated with a given
+ * {@link AttributeFilterContext}.
+ */
+ @Nonnull private Function<AttributeFilterContext,ProxiedRequesterContext> proxiesFromFilterLookupStrategy;
/** Whether to treat resolver errors as equivalent to resolving no attributes. */
private boolean maskFailures;
@@ -136,17 +149,19 @@ public class FilterAttributes extends AbstractProfileAction {
new ChildContextLookup<>(SAMLMetadataContext.class),
Functions.compose(new ChildContextLookup<>(SAMLPeerEntityContext.class),
new InboundMessageContextLookup()));
-
+
// This is always set to navigate to the root context and then apply the previous function.
- metadataFromFilterLookupStrategy = Functions.compose(
- new Function<ProfileRequestContext,SAMLMetadataContext>() {
- @Override
- public SAMLMetadataContext apply(final ProfileRequestContext input) {
- return metadataContextLookupStrategy.apply(input);
- }
- },
+ metadataFromFilterLookupStrategy = Functions.compose(metadataContextLookupStrategy,
new RootContextLookup<AttributeFilterContext,ProfileRequestContext>());
+ // Default: inbound msg context -> child
+ proxiedRequesterContextLookupStrategy = Functions.compose(
+ new ChildContextLookup<>(ProxiedRequesterContext.class), new InboundMessageContextLookup());
+
+ // This is always set to navigate to the root context and then apply the previous function.
+ proxiesFromFilterLookupStrategy = Functions.compose(proxiedRequesterContextLookupStrategy,
+ new RootContextLookup<AttributeFilterContext,ProfileRequestContext>());
+
// Defaults to ProfileRequestContext -> RelyingPartyContext -> AttributeFilterContext.
filterContextCreationStrategy = Functions.compose(new ChildContextLookup<>(AttributeFilterContext.class, true),
new ChildContextLookup<ProfileRequestContext,RelyingPartyContext>(RelyingPartyContext.class));
@@ -246,10 +261,9 @@ public class FilterAttributes extends AbstractProfileAction {
/**
* Set the strategy used to locate the {@link SAMLMetadataContext} associated with a given
* {@link ProfileRequestContext}. Also sets the strategy to find the {@link SAMLMetadataContext}
- * from the {@link AttributeFilterContext};
- * SAMLMetadataContext
- * @param strategy strategy used to locate the {@link AuthenticationContext} associated with a given
- * {@link ProfileRequestContext}
+ * from the {@link AttributeFilterContext}.
+ *
+ * @param strategy lookup strategy
*/
public void setMetadataContextLookupStrategy(
@Nonnull final Function<ProfileRequestContext,SAMLMetadataContext> strategy) {
@@ -262,6 +276,25 @@ public class FilterAttributes extends AbstractProfileAction {
}
/**
+ * Set the strategy used to locate the {@link ProxiedRequesterContext} associated with a given
+ * {@link ProfileRequestContext}. Also sets the strategy to find the {@link ProxiedRequesterContext}
+ * from the {@link AttributeFilterContext}.
+ *
+ * @param strategy lookup strategy
+ *
+ * @since 3.4.0
+ */
+ public void setProxiedRequesterContextLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,ProxiedRequesterContext> strategy) {
+ ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+ proxiedRequesterContextLookupStrategy =
+ Constraint.isNotNull(strategy, "ProxiedRequesterContext lookup strategy cannot be null");
+ proxiesFromFilterLookupStrategy = Functions.compose(proxiedRequesterContextLookupStrategy,
+ new RootContextLookup<AttributeFilterContext,ProfileRequestContext>());
+ }
+
+ /**
* Set whether to treat resolution failure as equivalent to resolving no attributes.
*
* <p>This matches the behavior of V2.</p>
@@ -389,6 +422,7 @@ public class FilterAttributes extends AbstractProfileAction {
}
filterContext.setRequesterMetadataContextLookupStrategy(metadataFromFilterLookupStrategy);
+ filterContext.setProxiedRequesterContextLookupStrategy(proxiesFromFilterLookupStrategy);
// If the filter context doesn't have a set of attributes to filter already
// then look for them in the AttributeContext.
diff --git a/idp-schema/src/main/resources/schema/shibboleth-afp.xsd b/idp-schema/src/main/resources/schema/shibboleth-afp.xsd
index 9a4714d..6a818c7 100644
--- a/idp-schema/src/main/resources/schema/shibboleth-afp.xsd
+++ b/idp-schema/src/main/resources/schema/shibboleth-afp.xsd
@@ -327,6 +327,17 @@
</complexContent>
</complexType>
+ <complexType name="ProxiedRequester">
+ <annotation>
+ <documentation>
+ A match function that matches a proxied attribute requester against the specified value.
+ </documentation>
+ </annotation>
+ <complexContent>
+ <extension base="afp:StringMatchType"/>
+ </complexContent>
+ </complexType>
+
<complexType name="Issuer">
<annotation>
<documentation>
@@ -427,6 +438,17 @@
</complexContent>
</complexType>
+ <complexType name="ProxiedRequesterRegex">
+ <annotation>
+ <documentation>
+ A match function that matches a proxied attribute requester against the specified regular expression.
+ </documentation>
+ </annotation>
+ <complexContent>
+ <extension base="afp:RegexMatchType"/>
+ </complexContent>
+ </complexType>
+
<complexType name="IssuerRegex">
<annotation>
<documentation>
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list