[java-identity-provider] branch master updated: Extend c14n variant to Subject DataConnector.
Scott Cantor
cantor.2 at osu.edu
Mon Nov 4 16:01:14 EST 2019
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=09d2671db67a48dca8810013a4de9606916c4e43
The following commit(s) were added to refs/heads/master by this push:
new 09d2671 Extend c14n variant to Subject DataConnector.
09d2671 is described below
commit 09d2671db67a48dca8810013a4de9606916c4e43
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Mon Nov 4 16:01:11 2019 -0500
Extend c14n variant to Subject DataConnector.
---
.../resolver/dc/impl/SubjectDataConnector.java | 86 ++++++++++++++++++++--
.../resolver/dc/impl/SubjectDataConnectorTest.java | 38 +++++++++-
.../SubjectDerivedAttributeDefinitionParser.java | 9 ++-
.../spring/dc/impl/SubjectDataConnectorParser.java | 9 ++-
.../spring/dc/SubjectDataConnectorParserTest.java | 1 +
.../spring/dc/resolver/subjectAttributes.xml | 1 +
.../schema/shibboleth-attribute-resolver.xsd | 8 ++
7 files changed, 136 insertions(+), 16 deletions(-)
diff --git a/idp-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/impl/SubjectDataConnector.java b/idp-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/impl/SubjectDataConnector.java
index 52203c4..4b6913d 100644
--- a/idp-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/impl/SubjectDataConnector.java
+++ b/idp-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/impl/SubjectDataConnector.java
@@ -17,12 +17,14 @@
package net.shibboleth.idp.attribute.resolver.dc.impl;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe;
import javax.security.auth.Subject;
@@ -36,8 +38,11 @@ import net.shibboleth.idp.attribute.resolver.AbstractDataConnector;
import net.shibboleth.idp.attribute.resolver.ResolutionException;
import net.shibboleth.idp.attribute.resolver.context.AttributeResolutionContext;
import net.shibboleth.idp.attribute.resolver.context.AttributeResolverWorkContext;
+import net.shibboleth.idp.authn.context.SubjectCanonicalizationContext;
import net.shibboleth.idp.authn.context.SubjectContext;
+import net.shibboleth.idp.authn.context.navigate.SubjectCanonicalizationContextSubjectLookupFunction;
import net.shibboleth.idp.authn.principal.IdPAttributePrincipal;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
import net.shibboleth.utilities.java.support.component.ComponentSupport;
import net.shibboleth.utilities.java.support.logic.Constraint;
@@ -45,6 +50,8 @@ import net.shibboleth.utilities.java.support.logic.Constraint;
* A {@link net.shibboleth.idp.attribute.resolver.DataConnector} that extracts all
* {@link IdPAttributePrincipal} objects from the {@link Subject} objects associated
* with the request.
+ *
+ * @since 4.0.0
*/
@ThreadSafe
public class SubjectDataConnector extends AbstractDataConnector {
@@ -52,9 +59,15 @@ public class SubjectDataConnector extends AbstractDataConnector {
/** Class logger. */
@Nonnull private final Logger log = LoggerFactory.getLogger(SubjectDataConnector.class);
+ /** Flag denoting whether plugin is being used for subject c14n or standard usage. */
+ private boolean forCanonicalization;
+
/** Strategy used to locate the {@link SubjectContext} to use. */
@Nonnull private Function<ProfileRequestContext,SubjectContext> scLookupStrategy;
+ /** Strategy used to locate the {@link Subject} to use. */
+ @Nullable private Function<ProfileRequestContext,Subject> subjectLookupStrategy;
+
/** Controls handling of empty results. */
private boolean noResultIsError;
@@ -64,6 +77,30 @@ public class SubjectDataConnector extends AbstractDataConnector {
}
/**
+ * Gets whether the connector is being used during Subject Canonicalization, causing
+ * auto-installation of an alternate Subject lookup strategy.
+ *
+ * @return whether connector is being used during c14n
+ */
+ public boolean isForCanonicalization() {
+ return forCanonicalization;
+ }
+
+ /**
+ * Sets whether the connector is being used during Subject Canonicalization, causing
+ * auto-installation of an alternate Subject lookup strategy.
+ *
+ * <p>Defaults to false.</p>
+ *
+ * @param flag flag to set
+ */
+ public void setForCanonicalization(final boolean flag) {
+ ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+ forCanonicalization = flag;
+ }
+
+ /**
* Sets the strategy used to locate the {@link SubjectContext} associated with a given
* {@link AttributeResolutionContext}.
*
@@ -77,6 +114,19 @@ public class SubjectDataConnector extends AbstractDataConnector {
}
/**
+ * Sets the strategy used to locate a {@link Subject} associated with a given
+ * {@link AttributeResolutionContext}.
+ *
+ * @param strategy strategy used to locate a {@link Subject} associated with a given
+ * {@link AttributeResolutionContext}
+ */
+ public void setSubjectLookupStrategy(@Nullable final Function<ProfileRequestContext,Subject> strategy) {
+ ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+ subjectLookupStrategy = strategy;
+ }
+
+ /**
* Gets whether obtaining no results should be treated as an error.
*
* @return whether obtaining no results should be treated as an error
@@ -97,6 +147,18 @@ public class SubjectDataConnector extends AbstractDataConnector {
noResultIsError = flag;
}
+
+ /** {@inheritDoc} */
+ @Override protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+
+ if (forCanonicalization && subjectLookupStrategy == null) {
+ log.debug("{} Marked for use during canonicalication, auto-installing Subject lookup strategy",
+ getLogPrefix());
+ subjectLookupStrategy = new SubjectCanonicalizationContextSubjectLookupFunction().compose(
+ new ChildContextLookup<>(SubjectCanonicalizationContext.class));
+ }
+ }
/** {@inheritDoc} */
@Override
@@ -106,19 +168,27 @@ public class SubjectDataConnector extends AbstractDataConnector {
ComponentSupport.ifNotInitializedThrowUninitializedComponentException(this);
ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
- final SubjectContext sc = scLookupStrategy.compose(getProfileContextStrategy()).apply(resolutionContext);
- if (sc == null || sc.getSubjects().isEmpty()) {
- if (noResultIsError) {
- throw new ResolutionException("No Subjects available to obtain attributes");
+ Collection<Subject> subjects = Collections.emptyList();
+
+ if (subjectLookupStrategy != null) {
+ final Subject subject = subjectLookupStrategy.apply(getProfileContextStrategy().apply(resolutionContext));
+ if (subject == null) {
+ log.debug("{} No Subject returned from lookup, no attributes resolved", getLogPrefix());
+ return Collections.emptyMap();
}
- log.debug("{} Obtained no attributes from Subjects for principal '{}'", getLogPrefix(),
- resolutionContext.getPrincipal());
- return Collections.emptyMap();
+ subjects = Collections.singletonList(subject);
+ } else {
+ final SubjectContext cs = scLookupStrategy.apply(getProfileContextStrategy().apply(resolutionContext));
+ if (cs == null || cs.getSubjects().isEmpty()) {
+ log.debug("{} No Subjects returned from SubjectContext lookup, no attributes resolved", getLogPrefix());
+ return Collections.emptyMap();
+ }
+ subjects = cs.getSubjects();
}
final Map<String,IdPAttribute> results = new HashMap<>();
- for (final Subject subject : sc.getSubjects()) {
+ for (final Subject subject : subjects) {
for (final IdPAttributePrincipal principal : subject.getPrincipals(IdPAttributePrincipal.class)) {
results.put(principal.getName(), principal.getAttribute());
}
diff --git a/idp-attribute-resolver-impl/src/test/java/net/shibboleth/idp/attribute/resolver/dc/impl/SubjectDataConnectorTest.java b/idp-attribute-resolver-impl/src/test/java/net/shibboleth/idp/attribute/resolver/dc/impl/SubjectDataConnectorTest.java
index b2c18d9..3e0fb62 100644
--- a/idp-attribute-resolver-impl/src/test/java/net/shibboleth/idp/attribute/resolver/dc/impl/SubjectDataConnectorTest.java
+++ b/idp-attribute-resolver-impl/src/test/java/net/shibboleth/idp/attribute/resolver/dc/impl/SubjectDataConnectorTest.java
@@ -33,6 +33,7 @@ import net.shibboleth.idp.attribute.StringAttributeValue;
import net.shibboleth.idp.attribute.resolver.ResolutionException;
import net.shibboleth.idp.attribute.resolver.context.AttributeResolutionContext;
import net.shibboleth.idp.authn.AuthenticationResult;
+import net.shibboleth.idp.authn.context.SubjectCanonicalizationContext;
import net.shibboleth.idp.authn.context.SubjectContext;
import net.shibboleth.idp.authn.principal.IdPAttributePrincipal;
import net.shibboleth.idp.saml.authn.principal.AuthenticationMethodPrincipal;
@@ -45,7 +46,6 @@ public class SubjectDataConnectorTest {
/** Simple result. */
private static final String SIMPLE_VALUE = "simple";
-
@Test public void simpleValue() throws ComponentInitializationException, ResolutionException {
final List<IdPAttributeValue> list = new ArrayList<>(2);
list.add(new StringAttributeValue(SIMPLE_VALUE));
@@ -79,7 +79,41 @@ public class SubjectDataConnectorTest {
assertTrue(copy.getValues().contains(new StringAttributeValue(SIMPLE_VALUE)));
assertTrue(copy.getValues().contains(new StringAttributeValue(SIMPLE_VALUE + "2")));
}
-
+
+ @Test public void simpleValueViaC14N() throws ComponentInitializationException, ResolutionException {
+ final List<IdPAttributeValue> list = new ArrayList<>(2);
+ list.add(new StringAttributeValue(SIMPLE_VALUE));
+ list.add(new StringAttributeValue(SIMPLE_VALUE + "2"));
+
+ final IdPAttribute attr = new IdPAttribute("wibble");
+ attr.setValues(list);
+
+ final SubjectDataConnector defn = new SubjectDataConnector();
+ defn.setId("pDAD");
+ defn.setForCanonicalization(true);
+ defn.initialize();
+
+ final AttributeResolutionContext ctx =
+ TestSources.createResolutionContext(TestSources.PRINCIPAL_ID, TestSources.IDP_ENTITY_ID,
+ TestSources.SP_ENTITY_ID);
+ final SubjectCanonicalizationContext sc = ctx.getParent().getSubcontext(SubjectCanonicalizationContext.class, true);
+ final Subject subject = new Subject();
+ subject.getPrincipals().add(new IdPAttributePrincipal(attr));
+ subject.getPrincipals().add(new AuthenticationMethodPrincipal(SIMPLE_VALUE + "2"));
+ sc.setSubject(subject);
+
+
+ final Map<String,IdPAttribute> results = defn.resolve(ctx);
+
+ assertEquals(1, results.size());
+
+ final IdPAttribute copy = results.get("wibble");
+
+ assertEquals(copy.getValues().size(), 2);
+ assertTrue(copy.getValues().contains(new StringAttributeValue(SIMPLE_VALUE)));
+ assertTrue(copy.getValues().contains(new StringAttributeValue(SIMPLE_VALUE + "2")));
+ }
+
@Test public void emptyOk() throws ComponentInitializationException, ResolutionException {
final SubjectDataConnector defn = new SubjectDataConnector();
diff --git a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/ad/impl/SubjectDerivedAttributeDefinitionParser.java b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/ad/impl/SubjectDerivedAttributeDefinitionParser.java
index 033908b..72ec4d4 100644
--- a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/ad/impl/SubjectDerivedAttributeDefinitionParser.java
+++ b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/ad/impl/SubjectDerivedAttributeDefinitionParser.java
@@ -27,6 +27,7 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;
+import net.shibboleth.ext.spring.util.SpringSupport;
import net.shibboleth.idp.attribute.resolver.ad.impl.ContextDerivedAttributeDefinition;
import net.shibboleth.idp.attribute.resolver.ad.impl.IdPAttributePrincipalValuesFunction;
import net.shibboleth.idp.attribute.resolver.ad.impl.SubjectDerivedAttributeValuesFunction;
@@ -62,16 +63,16 @@ public class SubjectDerivedAttributeDefinitionParser extends BaseAttributeDefini
super.doParse(config, parserContext, builder);
final String attributeName = StringSupport.trimOrNull(config.getAttributeNS(null, "principalAttributeName"));
final String functionRef = StringSupport.trimOrNull(config.getAttributeNS(null, "attributeValuesFunctionRef"));
- final String c14n = StringSupport.trimOrNull(config.getAttributeNS(null, "forCanonicalization"));
final BeanDefinitionBuilder contextFunctionBuilder =
BeanDefinitionBuilder.genericBeanDefinition(SubjectDerivedAttributeValuesFunction.class);
contextFunctionBuilder.addPropertyValue("id", getDefinitionId());
- if (c14n != null) {
- contextFunctionBuilder.addPropertyValue("forCanonicalization", c14n);
+ if (config.hasAttributeNS(null, "forCanonicalization")) {
+ contextFunctionBuilder.addPropertyValue("forCanonicalization",
+ SpringSupport.getStringValueAsBoolean(config.getAttributeNS(null, "forCanonicalization")));
}
-
+
if (null != attributeName) {
if (null != functionRef) {
log.warn("{} only one of \"principalAttributeName\" or \"attributeValuesFunctionRef\""
diff --git a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/dc/impl/SubjectDataConnectorParser.java b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/dc/impl/SubjectDataConnectorParser.java
index f2be591..9758fde 100644
--- a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/dc/impl/SubjectDataConnectorParser.java
+++ b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/dc/impl/SubjectDataConnectorParser.java
@@ -46,8 +46,13 @@ public class SubjectDataConnectorParser extends AbstractDataConnectorParser {
@Nonnull final BeanDefinitionBuilder builder) {
if (config.hasAttributeNS(null, "noResultIsError")) {
- builder.addPropertyValue("noResultIsError", SpringSupport.getStringValueAsBoolean(
- config.getAttributeNS(null, "noResultIsError")));
+ builder.addPropertyValue("noResultIsError",
+ SpringSupport.getStringValueAsBoolean(config.getAttributeNS(null, "noResultIsError")));
+ }
+
+ if (config.hasAttributeNS(null, "forCanonicalization")) {
+ builder.addPropertyValue("forCanonicalization",
+ SpringSupport.getStringValueAsBoolean(config.getAttributeNS(null, "forCanonicalization")));
}
}
diff --git a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/dc/SubjectDataConnectorParserTest.java b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/dc/SubjectDataConnectorParserTest.java
index a4ebdf2..62d406e 100644
--- a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/dc/SubjectDataConnectorParserTest.java
+++ b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/dc/SubjectDataConnectorParserTest.java
@@ -40,6 +40,7 @@ public class SubjectDataConnectorParserTest extends BaseAttributeDefinitionParse
assertTrue(connector.getExportAttributes().contains("foo"));
assertTrue(connector.getExportAttributes().contains("bar"));
assertTrue(connector.isNoResultIsError());
+ assertTrue(connector.isForCanonicalization());
}
@Test(expectedExceptions = {BeanCreationException.class}) public void emptyNoResultIsError() {
diff --git a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/dc/resolver/subjectAttributes.xml b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/dc/resolver/subjectAttributes.xml
index 0877943..73f757e 100644
--- a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/dc/resolver/subjectAttributes.xml
+++ b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/dc/resolver/subjectAttributes.xml
@@ -3,4 +3,5 @@
xmlns="urn:mace:shibboleth:2.0:resolver" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
exportAttributes="foo bar"
noResultIsError="true"
+ forCanonicalization="1"
xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd" />
diff --git a/idp-schema/src/main/resources/schema/shibboleth-attribute-resolver.xsd b/idp-schema/src/main/resources/schema/shibboleth-attribute-resolver.xsd
index 33c79a8..0512951 100644
--- a/idp-schema/src/main/resources/schema/shibboleth-attribute-resolver.xsd
+++ b/idp-schema/src/main/resources/schema/shibboleth-attribute-resolver.xsd
@@ -1548,6 +1548,14 @@
</documentation>
</annotation>
</attribute>
+ <attribute name="forCanonicalization" type="resolver:string">
+ <annotation>
+ <documentation>
+ If true, the source Subject is assumed to be undergoing C14N rather than the
+ usual post-authentication source. Defaults to false.
+ </documentation>
+ </annotation>
+ </attribute>
</extension>
</complexContent>
</complexType>
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list