[java-shib-attribute] branch main updated: Restore SubjectDerivedAttributeDefinitionPatser via deferred classes.

Scott Cantor cantor.2 at osu.edu
Mon Jul 11 15:19:56 UTC 2022


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

scantor 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=c9670ec46ba4e1f70ac862bce0e5bb665bc731a8

The following commit(s) were added to refs/heads/main by this push:
     new c9670ec46 Restore SubjectDerivedAttributeDefinitionPatser via deferred classes.
c9670ec46 is described below

commit c9670ec46ba4e1f70ac862bce0e5bb665bc731a8
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Mon Jul 11 11:19:53 2022 -0400

    Restore SubjectDerivedAttributeDefinitionPatser via deferred classes.
---
 .../SubjectDerivedAttributeDefinitionParser.java   | 141 +++++++++++++++++++++
 .../impl/AttributeResolverNamespaceHandler.java    |   7 +-
 2 files changed, 144 insertions(+), 4 deletions(-)

diff --git a/shib-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/ad/impl/SubjectDerivedAttributeDefinitionParser.java b/shib-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/ad/impl/SubjectDerivedAttributeDefinitionParser.java
new file mode 100644
index 000000000..12e5c3d1c
--- /dev/null
+++ b/shib-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/ad/impl/SubjectDerivedAttributeDefinitionParser.java
@@ -0,0 +1,141 @@
+/*
+ * 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.resolver.spring.ad.impl;
+
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.xml.namespace.QName;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.BeanCreationException;
+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.spring.ad.BaseAttributeDefinitionParser;
+import net.shibboleth.idp.attribute.resolver.spring.impl.AttributeResolverNamespaceHandler;
+import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
+
+/** Spring Bean Definition Parser for attribute definitions derived from the Principal. */
+public class SubjectDerivedAttributeDefinitionParser extends BaseAttributeDefinitionParser {
+
+    /** Schema type name. */
+    @Nonnull public static final QName TYPE_NAME_RESOLVER =
+            new QName(AttributeResolverNamespaceHandler.NAMESPACE, "SubjectDerivedAttribute");
+
+    /** Class name for sourcing values from Subject(s). */
+    @Nonnull @NotEmpty private static final String SUBJECT_DERIVED_CLASS_NAME =
+            "net.shibboleth.idp.authn.context.impl.SubjectDerivedAttributeValuesFunction"; 
+
+    /** Class name for sourcing values from Principal(s). */
+    @Nonnull @NotEmpty private static final String PRINCIPAL_DERIVED_CLASS_NAME =
+            "net.shibboleth.idp.authn.context.impl.IdPAttributePrincipalValuesFunction"; 
+
+    /** Class for sourcing values from Subject(s). */
+    @Nonnull private Class<? extends Function<?,?>> subjectDerivedClass;
+
+    /** Class for sourcing values from Principal(s). */
+    @Nonnull private Class<? extends Function<?,?>> principalDerivedClass;
+
+    /** Class logger. */
+    private final Logger log = LoggerFactory.getLogger(SubjectDerivedAttributeDefinitionParser.class);
+
+    /** Constructor. */
+    @SuppressWarnings("unchecked")
+    public SubjectDerivedAttributeDefinitionParser() {
+        try {
+            subjectDerivedClass = (Class<? extends Function<?, ?>>) Class.forName(SUBJECT_DERIVED_CLASS_NAME);
+            principalDerivedClass = (Class<? extends Function<?, ?>>) Class.forName(PRINCIPAL_DERIVED_CLASS_NAME);
+        } catch (final ClassNotFoundException e) {
+            log.error("Unable to load classes to support instantiation of this plugin type.");
+        }
+    }
+    
+    /** {@inheritDoc} */
+    @Override protected Class<ContextDerivedAttributeDefinition> getBeanClass(final Element element) {
+        return ContextDerivedAttributeDefinition.class;
+    }
+
+    /**
+     * {@inheritDoc}.
+     * 
+     * We inject an inferred function to derive the attributes from the Subject.
+     * 
+     * <p>
+     * If 'principalAttributeName' we also inject an inferred function to derive the attributes from a Principal. If
+     * 'attributeValueFunctionRef' the user has provided the function. {@link ContextDerivedAttributeDefinitionParser}
+     * handles the case when the user injects the top level function.
+     * </p>
+     */
+    @Override protected void doParse(@Nonnull final Element config, @Nonnull final ParserContext parserContext,
+            @Nonnull final BeanDefinitionBuilder builder) {
+        
+        if (subjectDerivedClass == null) {
+            throw new BeanCreationException("Unable to load class for subject-derived attribute function.");
+        }
+        
+        super.doParse(config, parserContext, builder);
+        final String attributeName = StringSupport.trimOrNull(config.getAttributeNS(null, "principalAttributeName"));
+        final String functionRef = StringSupport.trimOrNull(config.getAttributeNS(null, "attributeValuesFunctionRef"));
+        
+        final BeanDefinitionBuilder contextFunctionBuilder =
+                BeanDefinitionBuilder.genericBeanDefinition(subjectDerivedClass);
+        contextFunctionBuilder.setInitMethodName("initialize");
+        contextFunctionBuilder.setDestroyMethodName("destroy");
+        contextFunctionBuilder.addPropertyValue("id", getDefinitionId());
+
+        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\""
+                        + " should be provided. \"attributeValuesFunctionRef\" ignored", getLogPrefix());
+            }
+            
+            if (principalDerivedClass == null) {
+                throw new BeanCreationException("Unable to load class for principal-derived attribute function.");
+            }
+            
+            final BeanDefinitionBuilder principalValuesFunctionBuilder =
+                    BeanDefinitionBuilder.genericBeanDefinition(principalDerivedClass);
+            principalValuesFunctionBuilder.addPropertyValue("attributeName", attributeName);
+            contextFunctionBuilder.addPropertyValue("attributeValuesFunction",
+                    principalValuesFunctionBuilder.getBeanDefinition());
+        } else if (null != functionRef) {
+            contextFunctionBuilder.addPropertyReference("attributeValuesFunction", functionRef);
+        } else {
+            log.error("{} one of \"principalAttributeName\" or \"attributeValuesFunctionRef\" should be supplied."
+                    + " should be provided.", getLogPrefix());
+            throw new BeanCreationException("Misconfigured PrincipalDerivedAttribute.");
+        }
+        builder.addPropertyValue("attributeValuesFunction", contextFunctionBuilder.getBeanDefinition());
+    }
+
+    /** {@inheritDoc} */
+    @Override protected boolean failOnDependencies() {
+        return true;
+    }
+}
\ No newline at end of file
diff --git a/shib-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/impl/AttributeResolverNamespaceHandler.java b/shib-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/impl/AttributeResolverNamespaceHandler.java
index b9dca0289..596432c28 100644
--- a/shib-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/impl/AttributeResolverNamespaceHandler.java
+++ b/shib-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/impl/AttributeResolverNamespaceHandler.java
@@ -31,6 +31,7 @@ import net.shibboleth.idp.attribute.resolver.spring.ad.impl.SAML2NameIDAttribute
 import net.shibboleth.idp.attribute.resolver.spring.ad.impl.ScopedAttributeDefinitionParser;
 import net.shibboleth.idp.attribute.resolver.spring.ad.impl.ScriptedAttributeDefinitionParser;
 import net.shibboleth.idp.attribute.resolver.spring.ad.impl.SimpleAttributeDefinitionParser;
+import net.shibboleth.idp.attribute.resolver.spring.ad.impl.SubjectDerivedAttributeDefinitionParser;
 import net.shibboleth.idp.attribute.resolver.spring.ad.impl.DecryptedAttributeDefinitionParser;
 import net.shibboleth.idp.attribute.resolver.spring.ad.impl.TemplateAttributeDefinitionParser;
 import net.shibboleth.idp.attribute.resolver.spring.ad.mapped.impl.MappedAttributeDefinitionParser;
@@ -83,10 +84,8 @@ public class AttributeResolverNamespaceHandler extends BaseSpringNamespaceHandle
                 new PrincipalNameAttributeDefinitionParser());
         registerBeanDefinitionParser(RegexSplitAttributeDefinitionParser.TYPE_NAME_RESOLVER,
                 new RegexSplitAttributeDefinitionParser());
-
-        // TODO: implement in IdP layer
-        // registerBeanDefinitionParser(SubjectDerivedAttributeDefinitionParser.TYPE_NAME_RESOLVER,
-        //        new SubjectDerivedAttributeDefinitionParser());
+        registerBeanDefinitionParser(SubjectDerivedAttributeDefinitionParser.TYPE_NAME_RESOLVER,
+                new SubjectDerivedAttributeDefinitionParser());
         registerBeanDefinitionParser(ContextDerivedAttributeDefinitionParser.TYPE_NAME_RESOLVER,
                 new ContextDerivedAttributeDefinitionParser());
         registerBeanDefinitionParser(SAML1NameIdentifierAttributeDefinitionParser.TYPE_NAME_RESOLVER,

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


More information about the commits mailing list