[java-identity-provider] branch master updated: Extend SubjectDerivedAttributeDefinition
Scott Cantor
cantor.2 at osu.edu
Thu Oct 31 20:12:32 EDT 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=92937683701fcaaef09e7c78f929f9bb530fa126
The following commit(s) were added to refs/heads/master by this push:
new 9293768 Extend SubjectDerivedAttributeDefinition
9293768 is described below
commit 92937683701fcaaef09e7c78f929f9bb530fa126
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Thu Oct 31 20:12:26 2019 -0400
Extend SubjectDerivedAttributeDefinition
Support Subject undergoing c14n via boolean option.
---
.../SubjectDerivedAttributeValuesFunction.java | 42 +++++++++++++--
.../ContextDerivedAttributeDefinitionTest.java | 60 ++++++++++++++++++++++
.../SubjectDerivedAttributeDefinitionParser.java | 13 +++++
.../schema/shibboleth-attribute-resolver.xsd | 12 ++++-
4 files changed, 121 insertions(+), 6 deletions(-)
diff --git a/idp-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/ad/impl/SubjectDerivedAttributeValuesFunction.java b/idp-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/ad/impl/SubjectDerivedAttributeValuesFunction.java
index eebfcba..891ceb6 100644
--- a/idp-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/ad/impl/SubjectDerivedAttributeValuesFunction.java
+++ b/idp-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/ad/impl/SubjectDerivedAttributeValuesFunction.java
@@ -19,6 +19,8 @@ package net.shibboleth.idp.attribute.resolver.ad.impl;
import java.security.Principal;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
import java.util.List;
import java.util.function.Function;
@@ -59,6 +61,9 @@ public class SubjectDerivedAttributeValuesFunction extends AbstractIdentifiableI
*/
@NonnullAfterInit private Function<Principal,List<IdPAttributeValue>> attributeValuesFunction;
+ /** Strategy used to locate the {@link Subject} to use. */
+ @Nullable private Function<ProfileRequestContext,Subject> subjectLookupStrategy;
+
/** Constructor. */
public SubjectDerivedAttributeValuesFunction() {
scLookupStrategy = new ChildContextLookup<>(SubjectContext.class);
@@ -89,6 +94,20 @@ public class SubjectDerivedAttributeValuesFunction extends AbstractIdentifiableI
attributeValuesFunction = Constraint.isNotNull(strategy, "Attribute value lookup strategy cannot be null");
}
+ /**
+ * Sets the strategy used to locate a {@link Subject} associated with a given
+ * {@link net.shibboleth.idp.attribute.resolver.context.AttributeResolutionContext}.
+ *
+ * @param strategy strategy used to locate a {@link Subject} associated with a given
+ * {@link net.shibboleth.idp.attribute.resolver.context.AttributeResolutionContext}
+ */
+ public void setSubjectLookupStrategy(
+ @Nullable final Function<ProfileRequestContext,Subject> strategy) {
+ ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+ subjectLookupStrategy = strategy;
+ }
+
/** {@inheritDoc} */
@Override protected void doInitialize() throws ComponentInitializationException {
super.doInitialize();
@@ -100,15 +119,28 @@ public class SubjectDerivedAttributeValuesFunction extends AbstractIdentifiableI
/** {@inheritDoc} */
@Nullable public List<IdPAttributeValue> apply(@Nullable final ProfileRequestContext prc) {
- final SubjectContext cs = scLookupStrategy.apply(prc);
- if (cs == null) {
- log.debug("{} No SubjectContext returned from lookup strategy, no attribute resolved", getLogPrefix());
- return null;
+
+ Collection<Subject> subjects = Collections.emptyList();
+
+ if (subjectLookupStrategy != null) {
+ final Subject subject = subjectLookupStrategy.apply(prc);
+ if (subject == null) {
+ log.debug("{} No Subject returned from lookup, no attribute resolved", getLogPrefix());
+ return null;
+ }
+ subjects = Collections.singletonList(subject);
+ } else {
+ final SubjectContext cs = scLookupStrategy.apply(prc);
+ if (cs == null || cs.getSubjects().isEmpty()) {
+ log.debug("{} No Subjects returned from SubjectContext lookup, no attribute resolved", getLogPrefix());
+ return null;
+ }
+ subjects = cs.getSubjects();
}
final List<IdPAttributeValue> results = new ArrayList<>();
- for (final Subject subject : cs.getSubjects()) {
+ for (final Subject subject : subjects) {
for (final Principal principal : subject.getPrincipals()) {
final List<IdPAttributeValue> values = attributeValuesFunction.apply(principal);
if ((null != values) && !values.isEmpty()) {
diff --git a/idp-attribute-resolver-impl/src/test/java/net/shibboleth/idp/attribute/resolver/ad/impl/ContextDerivedAttributeDefinitionTest.java b/idp-attribute-resolver-impl/src/test/java/net/shibboleth/idp/attribute/resolver/ad/impl/ContextDerivedAttributeDefinitionTest.java
index 7eea0af..7279761 100644
--- a/idp-attribute-resolver-impl/src/test/java/net/shibboleth/idp/attribute/resolver/ad/impl/ContextDerivedAttributeDefinitionTest.java
+++ b/idp-attribute-resolver-impl/src/test/java/net/shibboleth/idp/attribute/resolver/ad/impl/ContextDerivedAttributeDefinitionTest.java
@@ -41,6 +41,7 @@ import net.shibboleth.idp.authn.principal.IdPAttributePrincipal;
import net.shibboleth.idp.saml.authn.principal.AuthenticationMethodPrincipal;
import net.shibboleth.idp.saml.impl.TestSources;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.utilities.java.support.logic.FunctionSupport;
/** Test for {@link SubjectDerivedAttributeValuesFunction}. */
public class ContextDerivedAttributeDefinitionTest {
@@ -49,6 +50,28 @@ public class ContextDerivedAttributeDefinitionTest {
private static final String SIMPLE_VALUE = "simple";
+ @Test public void noSubjectContext() throws ComponentInitializationException, ResolutionException {
+
+ final SubjectDerivedAttributeValuesFunction ctxValueFunction = new SubjectDerivedAttributeValuesFunction();
+ ctxValueFunction.setId("pDaD");
+ final IdPAttributePrincipalValuesFunction fn = new IdPAttributePrincipalValuesFunction();
+ fn.setAttributeName("wibble");
+ fn.doInitialize();
+ ctxValueFunction.setAttributeValuesFunction(fn);
+
+ final ContextDerivedAttributeDefinition defn = new ContextDerivedAttributeDefinition();
+ defn.setAttributeValuesFunction(ctxValueFunction);
+ defn.setId("pDAD");
+ defn.initialize();
+
+ final AttributeResolutionContext ctx =
+ TestSources.createResolutionContext(TestSources.PRINCIPAL_ID, TestSources.IDP_ENTITY_ID,
+ TestSources.SP_ENTITY_ID);
+
+ final IdPAttribute result = defn.resolve(ctx);
+ assertNull(result);
+ }
+
@Test public void simpleValue() throws ComponentInitializationException, ResolutionException {
final List<IdPAttributeValue> list = new ArrayList<>(2);
list.add(new StringAttributeValue(SIMPLE_VALUE));
@@ -87,6 +110,43 @@ public class ContextDerivedAttributeDefinitionTest {
assertTrue(foo.contains(new StringAttributeValue(SIMPLE_VALUE + "2")));
}
+ @Test public void simpleValueViaSubject() 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 Subject subject = new Subject();
+ subject.getPrincipals().add(new IdPAttributePrincipal(attr));
+ subject.getPrincipals().add(new AuthenticationMethodPrincipal(SIMPLE_VALUE + "2"));
+
+ final SubjectDerivedAttributeValuesFunction ctxValueFunction = new SubjectDerivedAttributeValuesFunction();
+ ctxValueFunction.setId("pDaD");
+ ctxValueFunction.setSubjectLookupStrategy(FunctionSupport.constant(subject));
+ final IdPAttributePrincipalValuesFunction fn = new IdPAttributePrincipalValuesFunction();
+ fn.setAttributeName("wibble");
+ fn.doInitialize();
+ ctxValueFunction.setAttributeValuesFunction(fn);
+
+ final ContextDerivedAttributeDefinition defn = new ContextDerivedAttributeDefinition();
+ defn.setAttributeValuesFunction(ctxValueFunction);
+ defn.setId("pDAD");
+ defn.initialize();
+
+ final AttributeResolutionContext ctx =
+ TestSources.createResolutionContext(TestSources.PRINCIPAL_ID, TestSources.IDP_ENTITY_ID,
+ TestSources.SP_ENTITY_ID);
+
+ final List<IdPAttributeValue> foo = defn.resolve(ctx).getValues();
+
+ assertEquals(2, foo.size());
+ assertTrue(foo.contains(new StringAttributeValue(SIMPLE_VALUE)));
+ assertTrue(foo.contains(new StringAttributeValue(SIMPLE_VALUE + "2")));
+ }
+
+
@Test public void empty() throws ComponentInitializationException, ResolutionException {
final List<IdPAttributeValue> list = Collections.emptyList();
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 9288add..83c7972 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
@@ -20,6 +20,7 @@ package net.shibboleth.idp.attribute.resolver.spring.ad.impl;
import javax.annotation.Nonnull;
import javax.xml.namespace.QName;
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.BeanCreationException;
@@ -32,7 +33,10 @@ import net.shibboleth.idp.attribute.resolver.ad.impl.IdPAttributePrincipalValues
import net.shibboleth.idp.attribute.resolver.ad.impl.SubjectDerivedAttributeValuesFunction;
import net.shibboleth.idp.attribute.resolver.spring.ad.BaseAttributeDefinitionParser;
import net.shibboleth.idp.attribute.resolver.spring.impl.AttributeResolverNamespaceHandler;
+import net.shibboleth.idp.authn.context.SubjectCanonicalizationContext;
+import net.shibboleth.idp.authn.context.navigate.SubjectCanonicalizationContextSubjectLookupFunction;
import net.shibboleth.utilities.java.support.primitive.StringSupport;
+import net.shibboleth.utilities.java.support.xml.AttributeSupport;
/** Spring Bean Definition Parser for attribute definitions derived from the Principal. */
public class SubjectDerivedAttributeDefinitionParser extends BaseAttributeDefinitionParser {
@@ -63,10 +67,19 @@ public class SubjectDerivedAttributeDefinitionParser extends BaseAttributeDefini
final String attributeName = StringSupport.trimOrNull(config.getAttributeNS(null, "principalAttributeName"));
final String functionRef = StringSupport.trimOrNull(config.getAttributeNS(null, "attributeValuesFunctionRef"));
+ final Boolean c14n = AttributeSupport.getAttributeValueAsBoolean(
+ config.getAttributeNodeNS(null, "forCanonicalization"));
+
final BeanDefinitionBuilder contextFunctionBuilder =
BeanDefinitionBuilder.genericBeanDefinition(SubjectDerivedAttributeValuesFunction.class);
contextFunctionBuilder.addPropertyValue("id", getDefinitionId());
+ if (c14n != null && c14n.booleanValue()) {
+ contextFunctionBuilder.addPropertyValue("subjectLookupStrategy",
+ new SubjectCanonicalizationContextSubjectLookupFunction().compose(
+ new ChildContextLookup<>(SubjectCanonicalizationContext.class)));
+ }
+
if (null != attributeName) {
if (null != functionRef) {
log.warn("{} only one of \"principalAttributeName\" or \"attributeValuesFunctionRef\""
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 29773d8..d15ac49 100644
--- a/idp-schema/src/main/resources/schema/shibboleth-attribute-resolver.xsd
+++ b/idp-schema/src/main/resources/schema/shibboleth-attribute-resolver.xsd
@@ -634,7 +634,6 @@
</documentation>
</annotation>
</attribute>
-
<attribute name="principalAttributeName" type="resolver:string">
<annotation>
<documentation>
@@ -643,6 +642,17 @@
</documentation>
</annotation>
</attribute>
+ <attribute name="forCanonicalization" type="boolean">
+ <annotation>
+ <documentation>
+ If true, the source Subject is assumed to be undergoing C14N rather than the
+ usual post-authentication source. Defaults to false.
+
+ This attribute is evaluated during parsing, so cannot be a property expression,
+ only a literal boolean value.
+ </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