[java-identity-provider] branch master updated: IDP-1456 - Apply attribute filtering code to inbound attributes

Scott Cantor cantor.2 at osu.edu
Thu May 30 21:49:16 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=abafe8d4d0ce088a6ede8f6928c3e7cd458f1690

The following commit(s) were added to refs/heads/master by this push:
       new  abafe8d   IDP-1456 - Apply attribute filtering code to inbound attributes
abafe8d is described below

commit abafe8d4d0ce088a6ede8f6928c3e7cd458f1690
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Thu May 30 21:49:08 2019 -0400

    IDP-1456 - Apply attribute filtering code to inbound attributes
    
    https://issues.shibboleth.net/jira/browse/IDP-1456
    
    Add inbound filtering to ValidateExternalAuthentication action.
    Wire AttributeFilter into external login flow validator.
---
 idp-attribute-filter-impl/pom.xml                  |  30 +++++
 .../impl/ValidateExternalAuthenticationTest.java   | 131 ++++++++++++++++++++
 .../idp/authn/ExternalAuthentication.java          |   9 +-
 idp-authn-impl/pom.xml                             |   5 +
 .../idp/authn/impl/ExternalAuthenticationImpl.java |  10 ++
 .../authn/impl/ValidateExternalAuthentication.java | 136 ++++++++++++++++++++-
 .../src/main/resources/system/conf/utilities.xml   |   6 +
 .../system/flows/authn/external-authn-beans.xml    |  12 +-
 8 files changed, 329 insertions(+), 10 deletions(-)

diff --git a/idp-attribute-filter-impl/pom.xml b/idp-attribute-filter-impl/pom.xml
index db9bce2..f336674 100644
--- a/idp-attribute-filter-impl/pom.xml
+++ b/idp-attribute-filter-impl/pom.xml
@@ -83,6 +83,15 @@
             <type>test-jar</type>
             <scope>test</scope>
         </dependency>
+
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>idp-profile-api</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>idp-saml-impl</artifactId>
@@ -99,6 +108,27 @@
         
         <dependency>
             <groupId>${project.groupId}</groupId>
+            <artifactId>idp-authn-api</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>idp-authn-impl</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>idp-authn-impl</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        
+        <dependency>
+            <groupId>${project.groupId}</groupId>
             <artifactId>idp-attribute-resolver-impl</artifactId>
             <version>${project.version}</version>
             <scope>test</scope>
diff --git a/idp-attribute-filter-impl/src/test/java/net/shibboleth/idp/attribute/filter/impl/ValidateExternalAuthenticationTest.java b/idp-attribute-filter-impl/src/test/java/net/shibboleth/idp/attribute/filter/impl/ValidateExternalAuthenticationTest.java
new file mode 100644
index 0000000..ba8d618
--- /dev/null
+++ b/idp-attribute-filter-impl/src/test/java/net/shibboleth/idp/attribute/filter/impl/ValidateExternalAuthenticationTest.java
@@ -0,0 +1,131 @@
+/*
+ * 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.impl;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+
+import net.shibboleth.idp.attribute.IdPAttribute;
+import net.shibboleth.idp.attribute.StringAttributeValue;
+import net.shibboleth.idp.attribute.context.AttributeContext;
+import net.shibboleth.idp.attribute.filter.AttributeFilter;
+import net.shibboleth.idp.attribute.filter.AttributeFilterPolicy;
+import net.shibboleth.idp.attribute.filter.AttributeRule;
+import net.shibboleth.idp.attribute.filter.Matcher;
+import net.shibboleth.idp.attribute.filter.impl.AttributeFilterImpl;
+import net.shibboleth.idp.attribute.filter.policyrule.filtercontext.impl.AttributeIssuerPolicyRule;
+import net.shibboleth.idp.authn.context.AuthenticationContext;
+import net.shibboleth.idp.authn.context.ExternalAuthenticationContext;
+import net.shibboleth.idp.authn.impl.BaseAuthenticationContextTest;
+import net.shibboleth.idp.authn.impl.ValidateExternalAuthentication;
+import net.shibboleth.idp.authn.principal.IdPAttributePrincipal;
+import net.shibboleth.idp.authn.principal.UsernamePrincipal;
+import net.shibboleth.idp.profile.ActionTestingSupport;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.utilities.java.support.service.MockReloadableService;
+import net.shibboleth.utilities.java.support.service.ReloadableService;
+
+import org.springframework.webflow.execution.Event;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+/** {@link ValidateExternalAuthentication} unit test using attributes. */
+public class ValidateExternalAuthenticationTest extends BaseAuthenticationContextTest {
+    
+    private ValidateExternalAuthentication action;
+    
+    @BeforeMethod public void setUp() throws Exception {
+        super.setUp();
+        
+        prc.getSubcontext(AuthenticationContext.class).setAttemptedFlow(authenticationFlows.get(0));
+
+        action = new ValidateExternalAuthentication(getFilterService());
+        action.setHttpServletRequest((HttpServletRequest) src.getExternalContext().getNativeRequest());
+        action.initialize();
+    }
+
+    @Test public void testPrincipalName() {
+        final AuthenticationContext ac = prc.getSubcontext(AuthenticationContext.class);
+        final ExternalAuthenticationContext eac = ac.getSubcontext(ExternalAuthenticationContext.class, true);
+        eac.setPrincipalName("jdoe");
+        
+        final IdPAttribute mail = new IdPAttribute("mail");
+        mail.setValues(Collections.singletonList(StringAttributeValue.valueOf("jdoe at example.org")));
+        eac.getSubcontext(AttributeContext.class, true).setIdPAttributes(Collections.singletonList(mail));
+        
+        final Event event = action.execute(src);
+        ActionTestingSupport.assertProceedEvent(event);
+        Assert.assertNotNull(ac.getAuthenticationResult());
+        Assert.assertFalse(ac.getAuthenticationResult().isPreviousResult());
+        Assert.assertEquals(ac.getAuthenticationResult().getSubject().getPrincipals(
+                UsernamePrincipal.class).iterator().next().getName(), "jdoe");
+        Assert.assertTrue(ac.getAuthenticationResult().getSubject().getPrincipals(IdPAttributePrincipal.class).isEmpty());
+    }
+    
+    @Test public void testAuthnAuthorities() {
+        final AuthenticationContext ac = prc.getSubcontext(AuthenticationContext.class);
+        final ExternalAuthenticationContext eac = ac.getSubcontext(ExternalAuthenticationContext.class, true);
+        eac.setPrincipalName("jdoe");
+        eac.getAuthenticatingAuthorities().addAll(Arrays.asList("foo", "bar", "baz"));
+
+        final IdPAttribute mail = new IdPAttribute("mail");
+        mail.setValues(Collections.singletonList(StringAttributeValue.valueOf("jdoe at example.org")));
+        eac.getSubcontext(AttributeContext.class, true).setIdPAttributes(Collections.singletonList(mail));
+
+        final Event event = action.execute(src);
+        ActionTestingSupport.assertProceedEvent(event);
+        Assert.assertNotNull(ac.getAuthenticationResult());
+        final Set<IdPAttributePrincipal> prin =
+                ac.getAuthenticationResult().getSubject().getPrincipals(IdPAttributePrincipal.class);
+        Assert.assertEquals(prin.size(), 1);
+        
+        final IdPAttribute copy = prin.iterator().next().getAttribute();
+        Assert.assertEquals(copy.getId(), "mail");
+        Assert.assertEquals(copy.getValues().size(), 1);
+        Assert.assertEquals(copy.getValues().get(0).getNativeValue(), "jdoe at example.org");
+    }
+    
+    private ReloadableService<AttributeFilter> getFilterService() throws ComponentInitializationException {
+        
+        final AttributeRule rule = new AttributeRule();
+        rule.setId("mailRule");
+        rule.setAttributeId("mail");
+        rule.setMatcher(Matcher.MATCHES_ALL);
+        rule.setIsDenyRule(false);
+        rule.initialize();
+        
+        final AttributeIssuerPolicyRule policyRule = new AttributeIssuerPolicyRule();
+        policyRule.setId("issuerRule");
+        policyRule.setMatchString("foo");
+        policyRule.initialize();
+        
+        final AttributeFilterPolicy policy = new AttributeFilterPolicy("mailPolicy",
+                policyRule, Collections.singletonList(rule));
+        policy.initialize();
+        
+        final AttributeFilterImpl filter = new AttributeFilterImpl("test", Collections.singletonList(policy));
+        filter.initialize();
+        
+        return new MockReloadableService(filter);
+    }
+
+}
\ No newline at end of file
diff --git a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/ExternalAuthentication.java b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/ExternalAuthentication.java
index 1f92f0b..a0814b7 100644
--- a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/ExternalAuthentication.java
+++ b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/ExternalAuthentication.java
@@ -54,7 +54,14 @@ public class ExternalAuthentication {
      * @since 3.4.0
      */
     @Nonnull @NotEmpty public static final String AUTHENTICATING_AUTHORITIES_KEY = "authnAuthorities";
-    
+
+    /** 
+     * Request attribute to which a collection of {@link IdPAttribute} objects may be bound.
+     * 
+     * @since 4.0.0
+     */
+    @Nonnull @NotEmpty public static final String ATTRIBUTES_KEY = "attributes";
+
     /** Request attribute to which an error message may be bound. */
     @Nonnull @NotEmpty public static final String AUTHENTICATION_ERROR_KEY = "authnError";
 
diff --git a/idp-authn-impl/pom.xml b/idp-authn-impl/pom.xml
index d63d6ae..b4cf885 100644
--- a/idp-authn-impl/pom.xml
+++ b/idp-authn-impl/pom.xml
@@ -29,6 +29,11 @@
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
+            <artifactId>idp-attribute-filter-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
             <artifactId>idp-authn-api</artifactId>
             <version>${project.version}</version>
         </dependency>
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ExternalAuthenticationImpl.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ExternalAuthenticationImpl.java
index e69d393..5d7301d 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ExternalAuthenticationImpl.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ExternalAuthenticationImpl.java
@@ -34,6 +34,8 @@ import org.opensaml.profile.context.ProfileRequestContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import net.shibboleth.idp.attribute.IdPAttribute;
+import net.shibboleth.idp.attribute.context.AttributeContext;
 import net.shibboleth.idp.authn.ExternalAuthentication;
 import net.shibboleth.idp.authn.ExternalAuthenticationException;
 import net.shibboleth.idp.authn.context.AuthenticationContext;
@@ -166,6 +168,14 @@ public class ExternalAuthenticationImpl extends ExternalAuthentication {
             extContext.getAuthenticatingAuthorities().addAll((Collection<String>) attr);
         }
         
+        attr = request.getAttribute(ATTRIBUTES_KEY);
+        if (attr != null && attr instanceof Collection<?>) {
+            extContext.getSubcontext(AttributeContext.class, true).setUnfilteredIdPAttributes(
+                    (Collection<IdPAttribute>) attr);
+            extContext.getSubcontext(AttributeContext.class).setIdPAttributes(
+                    (Collection<IdPAttribute>) attr);
+        }
+        
         attr = request.getAttribute(AUTHENTICATION_ERROR_KEY);
         if (attr != null && attr instanceof String) {
             extContext.setAuthnError((String) attr);
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateExternalAuthentication.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateExternalAuthentication.java
index b98bcf7..8573bab 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateExternalAuthentication.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateExternalAuthentication.java
@@ -20,23 +20,33 @@ package net.shibboleth.idp.authn.impl;
 import java.util.Collections;
 import java.util.Set;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 import javax.security.auth.Subject;
 
+import net.shibboleth.idp.attribute.IdPAttribute;
+import net.shibboleth.idp.attribute.context.AttributeContext;
+import net.shibboleth.idp.attribute.filter.AttributeFilter;
+import net.shibboleth.idp.attribute.filter.AttributeFilterException;
+import net.shibboleth.idp.attribute.filter.context.AttributeFilterContext;
 import net.shibboleth.idp.authn.AbstractValidationAction;
 import net.shibboleth.idp.authn.AuthnEventIds;
 import net.shibboleth.idp.authn.context.AuthenticationContext;
 import net.shibboleth.idp.authn.context.ExternalAuthenticationContext;
+import net.shibboleth.idp.authn.principal.IdPAttributePrincipal;
 import net.shibboleth.idp.authn.principal.ProxyAuthenticationPrincipal;
 import net.shibboleth.idp.authn.principal.UsernamePrincipal;
 import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
 import net.shibboleth.utilities.java.support.component.ComponentSupport;
+import net.shibboleth.utilities.java.support.service.ReloadableService;
+import net.shibboleth.utilities.java.support.service.ServiceableComponent;
 
 import org.opensaml.profile.action.ActionSupport;
 import org.opensaml.profile.action.EventIds;
 import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.saml.metadata.resolver.MetadataResolver;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -65,15 +75,36 @@ public class ValidateExternalAuthentication extends AbstractValidationAction {
     /** Class logger. */
     @Nonnull private final Logger log = LoggerFactory.getLogger(ValidateExternalAuthentication.class);
 
+    /** Service used to get the engine used to filter attributes. */
+    @Nullable private ReloadableService<AttributeFilter> attributeFilterService;
+
+    /** Optional supplemental metadata source for filtering. */
+    @Nullable private MetadataResolver metadataResolver;
+    
     /** A regular expression to apply for acceptance testing. */
     @Nullable private Pattern matchExpression;
     
     /** Context containing the result to validate. */
     @Nullable private ExternalAuthenticationContext extContext;
     
+    /** Context for externally supplied inbound attributes. */
+    @Nullable private AttributeContext attributeContext;
+    
     /** Constructor. */
     public ValidateExternalAuthentication() {
+        this(null);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param filterService optional filter service for inbound attributes
+     * 
+     * @since 4.0.0
+     */
+    public ValidateExternalAuthentication(@Nullable final ReloadableService<AttributeFilter> filterService) {
         setMetricName(DEFAULT_METRIC_NAME);
+        attributeFilterService = filterService;
     }
     
     /**
@@ -86,6 +117,19 @@ public class ValidateExternalAuthentication extends AbstractValidationAction {
         
         matchExpression = expression;
     }
+
+    /**
+     * Set a metadata source to use during filtering.
+     * 
+     * @param resolver metadata resolver
+     * 
+     * @since 4.0.0
+     */
+    public void setMetadataResolver(@Nullable final MetadataResolver resolver) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+        
+        metadataResolver = resolver;
+    }
     
     /** {@inheritDoc} */
     @Override
@@ -115,7 +159,7 @@ public class ValidateExternalAuthentication extends AbstractValidationAction {
     }
     
     /** {@inheritDoc} */
- // Checkstyle: ReturnCount|CyclomaticComplexity OFF
+ // Checkstyle: ReturnCount|CyclomaticComplexity|MethodLength OFF
     @Override
     protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext,
             @Nonnull final AuthenticationContext authenticationContext) {
@@ -175,6 +219,9 @@ public class ValidateExternalAuthentication extends AbstractValidationAction {
             log.debug("{} Disabling caching of authentication result", getLogPrefix());
             authenticationContext.setResultCacheable(false);
         }
+        
+        filterAttributes();
+        
         buildAuthenticationResult(profileRequestContext, authenticationContext);
         
         if (authenticationContext.getAuthenticationResult() != null) {
@@ -186,13 +233,22 @@ public class ValidateExternalAuthentication extends AbstractValidationAction {
             }
         }
     }
- // Checkstyle: ReturnCount|CyclomaticComplexity ON
-
+ // Checkstyle: ReturnCount|CyclomaticComplexity|MethodLength ON
+    
     /** {@inheritDoc} */
     @Override
     @Nonnull protected Subject populateSubject(@Nonnull final Subject subject) {
-        // Override supplied Subject with our own, after transferring over any custom Principals.
+        // Override supplied Subject with our own, after transferring over any custom Principals
+        // and adding any filtered inbound attributes.
         extContext.getSubject().getPrincipals().addAll(subject.getPrincipals());
+        
+        if (attributeContext != null && !attributeContext.getIdPAttributes().isEmpty()) {
+            log.debug("{} Adding filtered inbound attributes to Subject", getLogPrefix());
+            extContext.getSubject().getPrincipals().addAll(
+                attributeContext.getIdPAttributes().values().stream().map(
+                        (IdPAttribute a) -> new IdPAttributePrincipal(a)).collect(Collectors.toList()));
+        }
+        
         return extContext.getSubject();
     }
     
@@ -222,4 +278,76 @@ public class ValidateExternalAuthentication extends AbstractValidationAction {
         
         return true;
     }
+    
+    /**
+     * Check for inbound attributes and apply filtering.
+     */
+    private void filterAttributes() {
+        
+        attributeContext = extContext.getSubcontext(AttributeContext.class);
+        if (attributeContext == null) {
+            log.debug("{} No attribute context, no attributes to filter", getLogPrefix());
+            return;
+        }
+
+        if (attributeContext.getIdPAttributes().isEmpty()) {
+            log.debug("{} No attributes to filter", getLogPrefix());
+            return;
+        }
+
+        if (attributeFilterService == null) {
+            log.warn("{} No AttributeFilter service provided, clearing inbound attributes", getLogPrefix());
+            attributeContext.setIdPAttributes(null);
+            return;
+        }
+        
+        
+        final AttributeFilterContext filterContext = extContext.getSubcontext(AttributeFilterContext.class, true);
+        
+        populateFilterContext(filterContext);
+        
+        ServiceableComponent<AttributeFilter> component = null;
+
+        try {
+            component = attributeFilterService.getServiceableComponent();
+            if (null == component) {
+                log.error("{} Error while filtering inbound attributes: Invalid Attribute Filter configuration",
+                        getLogPrefix());
+                attributeContext.setIdPAttributes(null);
+            } else {
+                final AttributeFilter filter = component.getComponent();
+                filter.filterAttributes(filterContext);
+                filterContext.getParent().removeSubcontext(filterContext);
+                attributeContext.setIdPAttributes(filterContext.getFilteredIdPAttributes().values());
+            }
+        } catch (final AttributeFilterException e) {
+            log.error("{} Error while filtering inbound attributes", getLogPrefix(), e);
+            attributeContext.setIdPAttributes(null);
+        } finally {
+            if (null != component) {
+                component.unpinComponent();
+            }
+        }        
+    }
+    
+    /**
+     * Fill in the filter context data.
+     * 
+     * <p>This is a very minimally populated context with nothing much set except possibly issuer,
+     * based on the AuthenticationAuthorities data.</p>
+     * 
+     * @param filterContext context to populate
+     */
+    private void populateFilterContext(@Nonnull final AttributeFilterContext filterContext) {
+        
+        filterContext.setPrefilteredIdPAttributes(attributeContext.getIdPAttributes().values())
+            .setMetadataResolver(metadataResolver)
+            .setRequesterMetadataContextLookupStrategy(null)
+            .setProxiedRequesterContextLookupStrategy(null);
+        
+        if (!extContext.getAuthenticatingAuthorities().isEmpty()) {
+            filterContext.setAttributeIssuerID(extContext.getAuthenticatingAuthorities().iterator().next());
+        }
+    }
+
 }
\ No newline at end of file
diff --git a/idp-conf/src/main/resources/system/conf/utilities.xml b/idp-conf/src/main/resources/system/conf/utilities.xml
index df590e4..ba51221 100644
--- a/idp-conf/src/main/resources/system/conf/utilities.xml
+++ b/idp-conf/src/main/resources/system/conf/utilities.xml
@@ -146,12 +146,18 @@
         c:type="#{ T(net.shibboleth.idp.ui.context.RelyingPartyUIContext) }"
         c:createContext="true" />
 
+    <bean id="shibboleth.ChildLookup.AttributeContext"
+        class="org.opensaml.messaging.context.navigate.ChildContextLookup"
+        c:type="#{ T(net.shibboleth.idp.attribute.context.AttributeContext) }" />
     <bean id="shibboleth.ChildLookup.AuthenticationContext"
         class="org.opensaml.messaging.context.navigate.ChildContextLookup"
         c:type="#{ T(net.shibboleth.idp.authn.context.AuthenticationContext) }" />
     <bean id="shibboleth.ChildLookup.MultiFactorAuthenticationContext"
         class="org.opensaml.messaging.context.navigate.ChildContextLookup"
         c:type="#{ T(net.shibboleth.idp.authn.context.MultiFactorAuthenticationContext) }" />
+    <bean id="shibboleth.ChildLookup.ExternalAuthenticationContext"
+        class="org.opensaml.messaging.context.navigate.ChildContextLookup"
+        c:type="#{ T(net.shibboleth.idp.authn.context.ExternalAuthenticationContext) }" />
     <bean id="shibboleth.ChildLookup.SubjectContext"
         class="org.opensaml.messaging.context.navigate.ChildContextLookup"
         c:type="#{ T(net.shibboleth.idp.authn.context.SubjectContext) }" />
diff --git a/idp-conf/src/main/resources/system/flows/authn/external-authn-beans.xml b/idp-conf/src/main/resources/system/flows/authn/external-authn-beans.xml
index cfbd1ce..8d0a17a 100644
--- a/idp-conf/src/main/resources/system/flows/authn/external-authn-beans.xml
+++ b/idp-conf/src/main/resources/system/flows/authn/external-authn-beans.xml
@@ -25,11 +25,13 @@
     <import resource="../../../conf/authn/external-authn-config.xml" />
 
     <bean id="ValidateExternalAuthentication"
-            class="net.shibboleth.idp.authn.impl.ValidateExternalAuthentication" scope="prototype"
-            p:matchExpression="#{getObject('shibboleth.authn.External.matchExpression')}"
-            p:addDefaultPrincipals="#{getObject('shibboleth.authn.External.addDefaultPrincipals') ?: true}"
-            p:classifiedMessages-ref="shibboleth.authn.External.ClassifiedMessageMap"
-            p:resultCachingPredicate="#{getObject('shibboleth.authn.External.resultCachingPredicate')}" />
+        class="net.shibboleth.idp.authn.impl.ValidateExternalAuthentication" scope="prototype"
+        p:matchExpression="#{getObject('shibboleth.authn.External.matchExpression')}"
+        p:addDefaultPrincipals="#{getObject('shibboleth.authn.External.addDefaultPrincipals') ?: true}"
+        p:classifiedMessages-ref="shibboleth.authn.External.ClassifiedMessageMap"
+        p:resultCachingPredicate="#{getObject('shibboleth.authn.External.resultCachingPredicate')}"
+        c:filterService-ref="shibboleth.AttributeFilterService"
+        p:metadataResolver-ref="shibboleth.MetadataResolver" />
 
     <bean id="PopulateSubjectCanonicalizationContext"
         class="net.shibboleth.idp.authn.impl.PopulateSubjectCanonicalizationContext" scope="prototype"

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


More information about the commits mailing list