[java-identity-provider] branch main updated: IDP-2353 - C14n flow that runs a deployer-defined bean

Scott Cantor cantor.2 at osu.edu
Tue Feb 25 23:26:19 UTC 2025


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

scantor pushed a commit to branch main
in repository java-identity-provider.

View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=28a8aa2efc09fb81e7ff6a43f58da55ea36cc18c

The following commit(s) were added to refs/heads/main by this push:
     new 28a8aa2ef IDP-2353 - C14n flow that runs a deployer-defined bean
28a8aa2ef is described below

commit 28a8aa2efc09fb81e7ff6a43f58da55ea36cc18c
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Feb 25 18:26:13 2025 -0500

    IDP-2353 - C14n flow that runs a deployer-defined bean
    
    https://shibboleth.atlassian.net/browse/IDP-2353
    
    Convert c14n/x500 flow into procedural impl.
---
 .../shibboleth/idp/authn/SubjectCanonicalizer.java |   3 +
 .../authn/impl/SimpleSubjectCanonicalization.java  |  10 +-
 .../authn/impl/X500SubjectCanonicalization.java    | 167 +++++++++------------
 .../impl/X500SubjectCanonicalizationTest.java      |  96 +++++-------
 .../shibboleth/idp/conf/subject-c14n-system.xml    |  16 ++
 .../net/shibboleth/idp/conf/webflow-config.xml     |   1 -
 .../idp/flows/c14n/x500-subject-c14n-beans.xml     |  32 ----
 .../idp/flows/c14n/x500-subject-c14n-flow.xml      |  17 ---
 8 files changed, 134 insertions(+), 208 deletions(-)

diff --git a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/SubjectCanonicalizer.java b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/SubjectCanonicalizer.java
index d03089810..6c218ac6c 100644
--- a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/SubjectCanonicalizer.java
+++ b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/SubjectCanonicalizer.java
@@ -16,6 +16,8 @@ package net.shibboleth.idp.authn;
 
 import java.util.function.Function;
 
+import javax.annotation.concurrent.ThreadSafe;
+
 import org.opensaml.profile.action.EventIds;
 
 import net.shibboleth.idp.authn.context.SubjectCanonicalizationContext;
@@ -33,6 +35,7 @@ import net.shibboleth.idp.authn.context.SubjectCanonicalizationContext;
  * 
  * @since 5.2.0
  */
+ at ThreadSafe
 public interface SubjectCanonicalizer extends Function<SubjectCanonicalizationContext,String> {
 
 }
\ No newline at end of file
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/SimpleSubjectCanonicalization.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/SimpleSubjectCanonicalization.java
index 5d6927333..9846c23ab 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/SimpleSubjectCanonicalization.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/SimpleSubjectCanonicalization.java
@@ -27,19 +27,13 @@ import org.opensaml.profile.context.ProfileRequestContext;
 import net.shibboleth.idp.authn.AbstractSubjectCanonicalizer;
 import net.shibboleth.idp.authn.AuthnEventIds;
 import net.shibboleth.idp.authn.SubjectCanonicalizationException;
+import net.shibboleth.idp.authn.SubjectCanonicalizer;
 import net.shibboleth.idp.authn.context.SubjectCanonicalizationContext;
 import net.shibboleth.idp.authn.principal.UsernamePrincipal;
 
 /**
- * An action that operates on a {@link SubjectCanonicalizationContext} child of the current
- * {@link ProfileRequestContext}, and transforms the input {@link javax.security.auth.Subject}
+ * A {@link SubjectCanonicalizer} that transforms the input {@link javax.security.auth.Subject}
  * into a principal name by searching for one and only one {@link UsernamePrincipal} custom principal.
- * 
- * @event {@link org.opensaml.profile.action.EventIds#PROCEED_EVENT_ID}
- * @event {@link AuthnEventIds#INVALID_SUBJECT}
- * @pre <pre>ProfileRequestContext.getSubcontext(SubjectCanonicalizationContext.class, false) != null</pre>
- * @post <pre>SubjectCanonicalizationContext.getPrincipalName() != null
- *  || SubjectCanonicalizationContext.getException() != null</pre>
  */
 public class SimpleSubjectCanonicalization extends AbstractSubjectCanonicalizer {
     
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/X500SubjectCanonicalization.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/X500SubjectCanonicalization.java
index e74f0baa0..e3b0dbe5a 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/X500SubjectCanonicalization.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/X500SubjectCanonicalization.java
@@ -28,16 +28,16 @@ import org.cryptacular.x509.dn.Attribute;
 import org.cryptacular.x509.dn.NameReader;
 import org.cryptacular.x509.dn.RDN;
 import org.cryptacular.x509.dn.RDNSequence;
-import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventIds;
 import org.opensaml.profile.context.ProfileRequestContext;
 import org.opensaml.security.x509.X509Support;
 import org.slf4j.Logger;
 
-import net.shibboleth.idp.authn.AbstractSubjectCanonicalizationAction;
+import net.shibboleth.idp.authn.AbstractSubjectCanonicalizer;
 import net.shibboleth.idp.authn.AuthnEventIds;
 import net.shibboleth.idp.authn.SubjectCanonicalizationException;
+import net.shibboleth.idp.authn.SubjectCanonicalizer;
 import net.shibboleth.idp.authn.context.SubjectCanonicalizationContext;
-import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.primitive.LoggerFactory;
@@ -45,8 +45,7 @@ import net.shibboleth.shared.primitive.StringSupport;
 
 
 /**
- * An action that operates on a {@link SubjectCanonicalizationContext} child of the current
- * {@link ProfileRequestContext}, and transforms the input {@link javax.security.auth.Subject}
+ * A {@link SubjectCanonicalizer} that transforms the input {@link javax.security.auth.Subject}
  * into a principal name by searching for one and only one {@link X509Certificate} public credential,
  * or in its absence one and only one {@link X500Principal}.
  * 
@@ -55,17 +54,11 @@ import net.shibboleth.shared.primitive.StringSupport;
  * 
  * <p>Alternatively, a list of subjectAltName extension types may be specified, which takes precedence
  * over the subject, if a match is found.</p>
- * 
- * @event {@link org.opensaml.profile.action.EventIds#PROCEED_EVENT_ID}
- * @event {@link AuthnEventIds#INVALID_SUBJECT}
- * @pre <pre>ProfileRequestContext.getSubcontext(SubjectCanonicalizationContext.class) != null</pre>
- * @post <pre>SubjectCanonicalizationContext.getPrincipalName() != null
- *  || SubjectCanonicalizationContext.getException() != null</pre>
  */
-public class X500SubjectCanonicalization extends AbstractSubjectCanonicalizationAction {
+public class X500SubjectCanonicalization extends AbstractSubjectCanonicalizer {
 
     /** Common Name (CN) OID. */
-    private static final String CN_OID = "2.5.4.3";
+    @Nonnull @NotEmpty private static final String CN_OID = "2.5.4.3";
 
     /** Class logger. */
     @Nonnull private final Logger log = LoggerFactory.getLogger(X500SubjectCanonicalization.class);
@@ -75,13 +68,7 @@ public class X500SubjectCanonicalization extends AbstractSubjectCanonicalization
     
     /** OIDs to search for. */
     @Nonnull private List<String> objectIds;
-    
-    /** The certificate to operate on. */
-    @Nullable private X509Certificate certificate;
-    
-    /** The subject DN to operate on. */
-    @NonnullBeforeExec private X500Principal x500Principal;
-    
+        
     /** Constructor. */
     public X500SubjectCanonicalization() {
         subjectAltNameTypes = CollectionSupport.emptyList();
@@ -114,50 +101,33 @@ public class X500SubjectCanonicalization extends AbstractSubjectCanonicalization
     
     /** {@inheritDoc} */
     @Override
-    protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext, 
-            @Nonnull final SubjectCanonicalizationContext c14nContext) {
+    @Nonnull protected String doApply(@Nonnull final SubjectCanonicalizationContext c14nContext) {
 
-        final Subject subject = c14nContext.getSubject();
-        assert subject != null;
-        final Set<X509Certificate> certificates =
-                subject.getPublicCredentials(X509Certificate.class);
-        if (certificates != null && certificates.size() == 1) {
-            certificate = certificates.iterator().next();
-            assert certificate != null;
+
+        final X500Principal x500Principal;
+        final X509Certificate certificate = getCertificate(c14nContext);
+        if (certificate != null) {
             x500Principal = certificate.getSubjectX500Principal();
         } else {
-            final Set<X500Principal> principals = subject.getPrincipals(X500Principal.class);
-            if (principals != null && principals.size() == 1) {
-                x500Principal = principals.iterator().next();
-            }
+            x500Principal = getX500Principal(c14nContext);
         }
         
-        if (x500Principal != null) {
-            return super.doPreExecute(profileRequestContext, c14nContext);
+        if (x500Principal == null) {
+            c14nContext.setException(new SubjectCanonicalizationException(
+                    "Neither a single X509Certificate nor X500Principal were found"));
+            return AuthnEventIds.INVALID_SUBJECT;
         }
         
-        c14nContext.setException(new SubjectCanonicalizationException(
-                "Neither a single X509Certificate nor X500Principal were found"));
-        ActionSupport.buildEvent(profileRequestContext, AuthnEventIds.INVALID_SUBJECT);
-        return false;
-    }
-    
-    /** {@inheritDoc} */
- // Checkstyle: ReturnCount OFF
-    @Override
-    protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext, 
-            @Nonnull final SubjectCanonicalizationContext c14nContext) {
-
-        final X509Certificate localCopy = certificate;
-        if (localCopy != null && !subjectAltNameTypes.isEmpty()) {
+        
+        if (certificate != null && !subjectAltNameTypes.isEmpty()) {
             log.debug("{} Searching for subjectAltName types ({})", getLogPrefix(), subjectAltNameTypes);
-            final List<?> altnames = X509Support.getAltNames(localCopy, subjectAltNameTypes.toArray(new Integer[0]));
+            final List<?> altnames = X509Support.getAltNames(certificate, subjectAltNameTypes.toArray(new Integer[0]));
             assert altnames != null;
             for (final Object altname : altnames) {
                 if (altname instanceof String) {
                     log.debug("{} Extracted String-valued subjectAltName: {}", getLogPrefix(), altname);
                     c14nContext.setPrincipalName(applyTransforms((String) altname));
-                    return;
+                    return EventIds.PROCEED_EVENT_ID;
                 }
             }
             log.debug("{} No suitable subjectAltName extension");
@@ -174,20 +144,18 @@ public class X500SubjectCanonicalization extends AbstractSubjectCanonicalization
                 if (rdn != null) {
                     log.debug("{} Extracted RDN with OID {}: {}", getLogPrefix(), oid, rdn);
                     c14nContext.setPrincipalName(applyTransforms(rdn));
-                    return;
+                    return EventIds.PROCEED_EVENT_ID;
                 }
             }
             
             log.warn("{} Unable to extract a suitable RDN from DN: {}", getLogPrefix(), x509PrincipalName);
-            ActionSupport.buildEvent(profileRequestContext, AuthnEventIds.INVALID_SUBJECT);
+            return AuthnEventIds.INVALID_SUBJECT;
             
         } catch (final IllegalArgumentException e) {
             log.warn("{} Unable to parse subject DN: {}", getLogPrefix(),  x509PrincipalName, e);
-            ActionSupport.buildEvent(profileRequestContext, AuthnEventIds.INVALID_SUBJECT);
-            return;
+            return AuthnEventIds.INVALID_SUBJECT;
         }
     }
- // Checkstyle: ReturnCount ON
     
     /**
      * Find an RDN with the specified OID.
@@ -211,6 +179,47 @@ public class X500SubjectCanonicalization extends AbstractSubjectCanonicalization
         return null;
     }
      
+    /**
+     * Helper method that returns the first and only {@link X500Principal}, returning null otherwise.
+     * 
+     * @param c14nContext input context
+     * 
+     * @return the only matching principal or null
+     */
+    @Nullable private static X500Principal getX500Principal(@Nonnull final SubjectCanonicalizationContext c14nContext) {
+        
+        final Subject subject = c14nContext.getSubject();
+        if (subject != null) {
+            final Set<X500Principal> prins = subject.getPrincipals(X500Principal.class);
+            if (prins != null && prins.size() == 1) {
+                return prins.iterator().next();
+            }
+        }
+        
+        return null;
+    }
+
+    /**
+     * Helper method that returns the first and only {@link X509Certificate}, returning null otherwise.
+     * 
+     * @param c14nContext input context
+     * 
+     * @return the only certificate or null
+     */
+    @Nullable private static X509Certificate getCertificate(
+            @Nonnull final SubjectCanonicalizationContext c14nContext) {
+        
+        final Subject subject = c14nContext.getSubject();
+        if (subject != null) {
+            final Set<X509Certificate> certificates = subject.getPublicCredentials(X509Certificate.class);
+            if (certificates != null && certificates.size() == 1) {
+                return certificates.iterator().next();
+            }
+        }
+        
+        return null;
+    }
+
     /** A predicate that determines if this action can run or not. */
     public static class ActivationCondition implements Predicate<ProfileRequestContext> {
 
@@ -221,49 +230,17 @@ public class X500SubjectCanonicalization extends AbstractSubjectCanonicalization
                 final SubjectCanonicalizationContext c14nContext =
                         input.getSubcontext(SubjectCanonicalizationContext.class);
                 if (c14nContext != null) {
-                    return apply(input, c14nContext, false);
+                    if (getCertificate(c14nContext) != null || getX500Principal(c14nContext) != null) {
+                        return true;
+                    }
+                    
+                    c14nContext.setException(new SubjectCanonicalizationException(
+                            "Neither a single X509Certificate nor X500Principal were found"));
                 }
             }
             
             return false;
-        }
-
-        /**
-         * Helper method that runs either as part of the {@link Predicate} or directly from
-         * the {@link X500SubjectCanonicalization#doPreExecute(ProfileRequestContext, SubjectCanonicalizationContext)}
-         * method above.
-         * 
-         * @param profileRequestContext the current profile request context
-         * @param c14nContext   the current c14n context
-         * @param duringAction  true iff the method is run from the action above
-         * @return true iff the action can operate successfully on the candidate contexts
-         */
-        public boolean apply(@Nonnull final ProfileRequestContext profileRequestContext,
-                @Nonnull final SubjectCanonicalizationContext c14nContext, final boolean duringAction) {
-
-            final Subject subject = c14nContext.getSubject();
-            if (subject != null) {
-                final Set<X509Certificate> certificates =
-                        subject.getPublicCredentials(X509Certificate.class);
-                if (certificates != null && certificates.size() == 1) {
-                    return true;
-                }
-                
-                final Set<X500Principal> principals = subject.getPrincipals(X500Principal.class);
-                if (principals != null && principals.size() == 1) {
-                    return true;
-                }
-            }
-            
-            c14nContext.setException(new SubjectCanonicalizationException(
-                    "Neither a single X509Certificate nor X500Principal were found"));
-            if (duringAction) {
-                ActionSupport.buildEvent(profileRequestContext, AuthnEventIds.INVALID_SUBJECT);
-            }
-            
-            return false;
-        }
-        
+        }        
     }
 
 }
\ No newline at end of file
diff --git a/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/X500SubjectCanonicalizationTest.java b/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/X500SubjectCanonicalizationTest.java
index fcdcc12fd..3dbfc72a6 100644
--- a/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/X500SubjectCanonicalizationTest.java
+++ b/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/X500SubjectCanonicalizationTest.java
@@ -14,19 +14,17 @@
 
 package net.shibboleth.idp.authn.impl;
 
-import java.util.Arrays;
-
 import javax.security.auth.Subject;
 import javax.security.auth.x500.X500Principal;
 
 import net.shibboleth.idp.authn.AuthnEventIds;
 import net.shibboleth.idp.authn.context.SubjectCanonicalizationContext;
 import net.shibboleth.idp.authn.impl.testing.BaseAuthenticationContextTest;
-import net.shibboleth.idp.profile.testing.ActionTestingSupport;
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.collection.Pair;
 import net.shibboleth.shared.component.ComponentInitializationException;
 
-import org.springframework.webflow.execution.Event;
+import org.opensaml.profile.action.EventIds;
 import org.testng.Assert;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
@@ -41,24 +39,25 @@ public class X500SubjectCanonicalizationTest extends BaseAuthenticationContextTe
         super.setUp();
         
         action = new X500SubjectCanonicalization();
-        action.setTransforms(Arrays.asList(new Pair<>("^(.+)@osu\\.edu$", "$1")));
-        action.setObjectIds(Arrays.asList("1.2.840.113549.1.9.1", "0.9.2342.19200300.100.1.1"));
+        action.setId("c14n/x500");
+        action.setTransforms(CollectionSupport.singletonList(new Pair<>("^(.+)@osu\\.edu$", "$1")));
+        action.setObjectIds(CollectionSupport.listOf("1.2.840.113549.1.9.1", "0.9.2342.19200300.100.1.1"));
         action.initialize();
     }
     
     @Test public void testNoContext() {
-        final Event event = action.execute(src);
+        final String event = action.apply(null);
         
-        ActionTestingSupport.assertEvent(event, AuthnEventIds.INVALID_SUBJECT_C14N_CTX);
+        Assert.assertEquals(event, AuthnEventIds.INVALID_SUBJECT_C14N_CTX);
     }
 
     @Test public void testNoPrincipal() {
         final Subject subject = new Subject();
-        prc.ensureSubcontext(SubjectCanonicalizationContext.class).setSubject(subject);
+        final var ctx = prc.ensureSubcontext(SubjectCanonicalizationContext.class).setSubject(subject);
         
-        final Event event = action.execute(src);
+        final String event = action.apply(ctx);
         
-        ActionTestingSupport.assertEvent(event, AuthnEventIds.INVALID_SUBJECT);
+        Assert.assertEquals(event, AuthnEventIds.INVALID_SUBJECT);
         final SubjectCanonicalizationContext scc = prc.getSubcontext(SubjectCanonicalizationContext.class);
         assert scc != null;
         Assert.assertNotNull(scc.getException());
@@ -68,11 +67,11 @@ public class X500SubjectCanonicalizationTest extends BaseAuthenticationContextTe
         final Subject subject = new Subject();
         subject.getPrincipals().add(new X500Principal("CN=foo"));
         subject.getPrincipals().add(new X500Principal("CN=bar"));
-        prc.ensureSubcontext(SubjectCanonicalizationContext.class).setSubject(subject);
+        final var ctx = prc.ensureSubcontext(SubjectCanonicalizationContext.class).setSubject(subject);
         
-        final Event event = action.execute(src);
+        final String event = action.apply(ctx);
         
-        ActionTestingSupport.assertEvent(event, AuthnEventIds.INVALID_SUBJECT);
+        Assert.assertEquals(event, AuthnEventIds.INVALID_SUBJECT);
         final SubjectCanonicalizationContext scc = prc.getSubcontext(SubjectCanonicalizationContext.class);
         assert scc != null;
         Assert.assertNotNull(scc.getException());
@@ -81,90 +80,77 @@ public class X500SubjectCanonicalizationTest extends BaseAuthenticationContextTe
     @Test public void testNone() {
         final Subject subject = new Subject();
         subject.getPrincipals().add(new X500Principal("CN=foo at example.edu"));
-        prc.ensureSubcontext(SubjectCanonicalizationContext.class).setSubject(subject);
+        final var ctx = prc.ensureSubcontext(SubjectCanonicalizationContext.class).setSubject(subject);
         
-        final Event event = action.execute(src);
+        final String event = action.apply(ctx);
         
-        ActionTestingSupport.assertEvent(event, AuthnEventIds.INVALID_SUBJECT);
-        final SubjectCanonicalizationContext sc = prc.getSubcontext(SubjectCanonicalizationContext.class);
-        assert sc!= null && sc.getPrincipalName() ==null;
+        Assert.assertEquals(event, AuthnEventIds.INVALID_SUBJECT);
+        Assert.assertNull(ctx.getPrincipalName());
     }
     
     @Test public void testSuccess() {
         final Subject subject = new Subject();
         subject.getPrincipals().add(new X500Principal("EMAILADDRESS=foo at example.edu"));
-        prc.ensureSubcontext(SubjectCanonicalizationContext.class).setSubject(subject);
+        final var ctx = prc.ensureSubcontext(SubjectCanonicalizationContext.class).setSubject(subject);
         
-        final Event event = action.execute(src);
+        final String event = action.apply(ctx);
         
-        ActionTestingSupport.assertProceedEvent(event);
-        final SubjectCanonicalizationContext sc = prc.getSubcontext(SubjectCanonicalizationContext.class);
-        assert sc != null;
-        Assert.assertEquals(sc.getPrincipalName(), "foo at example.edu");
+        Assert.assertEquals(event, EventIds.PROCEED_EVENT_ID);
+        Assert.assertEquals(ctx.getPrincipalName(), "foo at example.edu");
     }
 
     @Test public void testComplex() {
         final Subject subject = new Subject();
         subject.getPrincipals().add(new X500Principal("EMAILADDRESS=foo at example.edu\\, EMAILADDRESS=bar at example.edu"));
-        prc.ensureSubcontext(SubjectCanonicalizationContext.class).setSubject(subject);
+        final var ctx = prc.ensureSubcontext(SubjectCanonicalizationContext.class).setSubject(subject);
         
-        final Event event = action.execute(src);
+        final String event = action.apply(ctx);
         
-        ActionTestingSupport.assertProceedEvent(event);
-        final SubjectCanonicalizationContext sc = prc.getSubcontext(SubjectCanonicalizationContext.class);
-        assert sc != null;
-        Assert.assertEquals(sc.getPrincipalName(), "foo at example.edu, EMAILADDRESS=bar at example.edu");
+        Assert.assertEquals(event, EventIds.PROCEED_EVENT_ID);
+        Assert.assertEquals(ctx.getPrincipalName(), "foo at example.edu, EMAILADDRESS=bar at example.edu");
     }
     
     @Test public void testTransform() {
         final Subject subject = new Subject();
         subject.getPrincipals().add(new X500Principal("EMAILADDRESS=foo at osu.edu"));
-        prc.ensureSubcontext(SubjectCanonicalizationContext.class).setSubject(subject);
+        final var ctx = prc.ensureSubcontext(SubjectCanonicalizationContext.class).setSubject(subject);
         
-        final Event event = action.execute(src);
+        final String event = action.apply(ctx);
         
-        ActionTestingSupport.assertProceedEvent(event);
-        final SubjectCanonicalizationContext sc = prc.getSubcontext(SubjectCanonicalizationContext.class);
-        assert sc != null;
-        Assert.assertEquals(sc.getPrincipalName(), "foo");
+        Assert.assertEquals(event, EventIds.PROCEED_EVENT_ID);
+        Assert.assertEquals(ctx.getPrincipalName(), "foo");
     }
     
     @Test public void testMultipleTypes() {
         final Subject subject = new Subject();
         subject.getPrincipals().add(new X500Principal("EMAILADDRESS=foo at example.edu, 0.9.2342.19200300.100.1.1=bar at example.edu"));
-        prc.ensureSubcontext(SubjectCanonicalizationContext.class).setSubject(subject);
+        final var ctx = prc.ensureSubcontext(SubjectCanonicalizationContext.class).setSubject(subject);
         
-        final Event event = action.execute(src);
+        final String event = action.apply(ctx);
         
-        ActionTestingSupport.assertProceedEvent(event);
-        final SubjectCanonicalizationContext sc = prc.getSubcontext(SubjectCanonicalizationContext.class);
-        assert sc != null;
-        Assert.assertEquals(sc.getPrincipalName(), "foo at example.edu");
+        Assert.assertEquals(event, EventIds.PROCEED_EVENT_ID);
+        Assert.assertEquals(ctx.getPrincipalName(), "foo at example.edu");
     }
 
     @Test public void testMultipleValues() {
         final Subject subject = new Subject();
         subject.getPrincipals().add(new X500Principal("EMAILADDRESS=foo at example.edu, EMAILADDRESS=bar at example.edu"));
-        prc.ensureSubcontext(SubjectCanonicalizationContext.class).setSubject(subject);
+        final var ctx = prc.ensureSubcontext(SubjectCanonicalizationContext.class).setSubject(subject);
         
-        final Event event = action.execute(src);
+        final String event = action.apply(ctx);
         
-        ActionTestingSupport.assertProceedEvent(event);
-        final SubjectCanonicalizationContext sc = prc.getSubcontext(SubjectCanonicalizationContext.class);
-        assert sc != null;
-        Assert.assertEquals(sc.getPrincipalName(), "foo at example.edu");
+        Assert.assertEquals(event, EventIds.PROCEED_EVENT_ID);
+        Assert.assertEquals(ctx.getPrincipalName(), "foo at example.edu");
     }
 
     @Test public void testSecondary() {
         final Subject subject = new Subject();
         subject.getPrincipals().add(new X500Principal("0.9.2342.19200300.100.1.1=bar at example.edu"));
-        prc.ensureSubcontext(SubjectCanonicalizationContext.class).setSubject(subject);
+        final var ctx = prc.ensureSubcontext(SubjectCanonicalizationContext.class).setSubject(subject);
         
-        final Event event = action.execute(src);
+        final String event = action.apply(ctx);
         
-        ActionTestingSupport.assertProceedEvent(event);
-        final SubjectCanonicalizationContext scc = prc.getSubcontext(SubjectCanonicalizationContext.class);
-        assert scc != null;
-        Assert.assertEquals(scc.getPrincipalName(), "bar at example.edu");
+        Assert.assertEquals(event, EventIds.PROCEED_EVENT_ID);
+        Assert.assertEquals(ctx.getPrincipalName(), "bar at example.edu");
     }
 }
\ No newline at end of file
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/subject-c14n-system.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/subject-c14n-system.xml
index c9542820e..1ff5972d2 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/subject-c14n-system.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/subject-c14n-system.xml
@@ -24,8 +24,15 @@
 
     <import resource="${idp.home}/conf/c14n/subject-c14n.xml" />
     
+    <!-- Property-driven defaults to be overridden. -->
+    <bean id="shibboleth.c14n.x500.SubjectAltNameTypes" parent="shibboleth.CommaDelimStringArray"
+        c:_0="#{'%{idp.c14n.x500.subjectAltNameTypes:}'.trim()}" />
+    <bean id="shibboleth.c14n.x500.ObjectIDs" parent="shibboleth.CommaDelimStringArray"
+        c:_0="#{'%{idp.c14n.x500.objectIDs:}'.trim()}" />
+
     <!-- Legacy compatibility. -->
     <import resource="conditional:%{idp.home}/conf/c14n/simple-subject-c14n-config.xml" />
+    <import resource="conditional:%{idp.home}/conf/c14n/x500-subject-c14n-config.xml" />
 
     <bean id="shibboleth.PostLoginSubjectCanonicalizationFlow" abstract="true"
         class="net.shibboleth.idp.authn.PostLoginSubjectCanonicalizationFlowDescriptor" />
@@ -44,6 +51,15 @@
     </bean>
 
     <bean id="c14n/x500" parent="shibboleth.PostLoginSubjectCanonicalizationFlow">
+        <property name="implementation">
+            <bean class="net.shibboleth.idp.authn.impl.X500SubjectCanonicalization"
+                p:subjectAltNameTypes-ref="shibboleth.c14n.x500.SubjectAltNameTypes"
+                p:objectIds-ref="shibboleth.c14n.x500.ObjectIDs"
+                p:lowercase="#{getObject('shibboleth.c14n.x500.Lowercase') ?: %{idp.c14n.x500.lowercase:false}}"
+                p:uppercase="#{getObject('shibboleth.c14n.x500.Uppercase') ?: %{idp.c14n.x500.uppercase:false}}"
+                p:trim="#{getObject('shibboleth.c14n.x500.Trim') ?: %{idp.c14n.x500.trim:true}}"
+                p:transforms="#{getObject('shibboleth.c14n.x500.Transforms')}" />
+        </property>
         <property name="activationCondition">
             <bean class="net.shibboleth.idp.authn.impl.X500SubjectCanonicalization.ActivationCondition" />
         </property>
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/webflow-config.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/webflow-config.xml
index 0fc0c2aa2..9f4d9249c 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/webflow-config.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/webflow-config.xml
@@ -99,7 +99,6 @@
                 <entry key="c14n" value="classpath:/net/shibboleth/idp/flows/c14n/subject-c14n-flow.xml" />
         
                 <!-- Standard post-login C14N methods. -->
-                <entry key="c14n/x500" value="classpath:/net/shibboleth/idp/flows/c14n/x500-subject-c14n-flow.xml" />
                 <entry key="c14n/attribute" value="classpath:/net/shibboleth/idp/flows/c14n/attribute-sourced-subject-c14n-flow.xml" />
         
                 <!--
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/c14n/x500-subject-c14n-beans.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/c14n/x500-subject-c14n-beans.xml
deleted file mode 100644
index b6b974930..000000000
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/c14n/x500-subject-c14n-beans.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:context="http://www.springframework.org/schema/context"
-       xmlns:util="http://www.springframework.org/schema/util"
-       xmlns:p="http://www.springframework.org/schema/p"
-       xmlns:c="http://www.springframework.org/schema/c"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
-                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
-                           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
-                           
-       default-init-method="initialize"
-       default-destroy-method="destroy">
-
-    <!-- Property-driven defaults to be overridden. -->
-    <bean id="shibboleth.c14n.x500.SubjectAltNameTypes" parent="shibboleth.CommaDelimStringArray"
-        c:_0="#{'%{idp.c14n.x500.subjectAltNameTypes:}'.trim()}" />
-    <bean id="shibboleth.c14n.x500.ObjectIDs" parent="shibboleth.CommaDelimStringArray"
-        c:_0="#{'%{idp.c14n.x500.objectIDs:}'.trim()}" />
-
-    <import resource="conditional:%{idp.home}/conf/c14n/x500-subject-c14n-config.xml" />
-    
-    <bean id="X500SubjectCanonicalization"
-        class="net.shibboleth.idp.authn.impl.X500SubjectCanonicalization" scope="prototype"
-        p:subjectAltNameTypes-ref="shibboleth.c14n.x500.SubjectAltNameTypes"
-        p:objectIds-ref="shibboleth.c14n.x500.ObjectIDs"
-        p:lowercase="#{getObject('shibboleth.c14n.x500.Lowercase') ?: %{idp.c14n.x500.lowercase:false}}"
-        p:uppercase="#{getObject('shibboleth.c14n.x500.Uppercase') ?: %{idp.c14n.x500.uppercase:false}}"
-        p:trim="#{getObject('shibboleth.c14n.x500.Trim') ?: %{idp.c14n.x500.trim:true}}"
-        p:transforms="#{getObject('shibboleth.c14n.x500.Transforms')}" />
-    
-</beans>
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/c14n/x500-subject-c14n-flow.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/c14n/x500-subject-c14n-flow.xml
deleted file mode 100644
index 988a74ffa..000000000
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/c14n/x500-subject-c14n-flow.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<flow xmlns="http://www.springframework.org/schema/webflow"
-      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-      xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow.xsd"
-      parent="c14n.abstract">
-
-    <!-- This is a one-step subflow that does Subject Canonicalization against an X500Principal. -->
-    
-    <action-state id="X500SubjectCanonicalization">
-        <evaluate expression="X500SubjectCanonicalization" />
-        <evaluate expression="'proceed'" />
-        
-        <transition on="proceed" to="proceed" />
-    </action-state>
-
-    <bean-import resource="x500-subject-c14n-beans.xml" />
-
-</flow>

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


More information about the commits mailing list