[java-identity-provider] branch main updated: IDP-2353 - C14n flow that runs a deployer-defined bean
Scott Cantor
cantor.2 at osu.edu
Tue Mar 4 17:18:16 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=afa184c88fdc60f8861f8ad5e7ef67e424911baf
The following commit(s) were added to refs/heads/main by this push:
new afa184c88 IDP-2353 - C14n flow that runs a deployer-defined bean
afa184c88 is described below
commit afa184c88fdc60f8861f8ad5e7ef67e424911baf
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Mar 4 12:17:44 2025 -0500
IDP-2353 - C14n flow that runs a deployer-defined bean
https://shibboleth.atlassian.net/browse/IDP-2353
Collapse c14n impls with flow descriptors to simplify wiring and code.
---
.../idp/authn/AbstractSubjectCanonicalizer.java | 3 +-
.../SubjectCanonicalizationFlowDescriptor.java | 38 +----
.../impl/SelectSubjectCanonicalizationFlow.java | 5 +-
.../shibboleth/idp/conf/subject-c14n-system.xml | 159 +++++++--------------
.../saml/nameid/AbstractNameIDCanonicalizer.java | 94 ++++++++++++
.../saml/nameid/impl/NameIDCanonicalization.java | 25 +---
.../impl/NameIdentifierCanonicalization.java | 27 +---
.../impl/CryptoTransientNameIDDecoderTest.java | 8 +-
.../CryptoTransientNameIdentifierDecoderTest.java | 9 +-
.../nameid/impl/NameIDCanonicalizationTest.java | 13 +-
.../impl/NameIdentifierCanonicalizationTest.java | 11 +-
.../idp/saml/nameid/impl/TransientDecoderTest.java | 8 +-
12 files changed, 174 insertions(+), 226 deletions(-)
diff --git a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractSubjectCanonicalizer.java b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractSubjectCanonicalizer.java
index fb374930d..c1a1cbd9c 100644
--- a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractSubjectCanonicalizer.java
+++ b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractSubjectCanonicalizer.java
@@ -29,7 +29,6 @@ import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
import net.shibboleth.shared.annotation.constraint.NotEmpty;
import net.shibboleth.shared.collection.CollectionSupport;
import net.shibboleth.shared.collection.Pair;
-import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
import net.shibboleth.shared.component.ComponentInitializationException;
import net.shibboleth.shared.logic.Constraint;
import net.shibboleth.shared.primitive.LoggerFactory;
@@ -38,7 +37,7 @@ import net.shibboleth.shared.primitive.StringSupport;
/**
* A base class for "stand-alone" subject c14n implementations.
*/
-public abstract class AbstractSubjectCanonicalizer extends AbstractIdentifiableInitializableComponent
+public abstract class AbstractSubjectCanonicalizer extends SubjectCanonicalizationFlowDescriptor
implements SubjectCanonicalizer {
/** Class logger. */
diff --git a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/SubjectCanonicalizationFlowDescriptor.java b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/SubjectCanonicalizationFlowDescriptor.java
index 0927800df..9a6dbcdb8 100644
--- a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/SubjectCanonicalizationFlowDescriptor.java
+++ b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/SubjectCanonicalizationFlowDescriptor.java
@@ -50,9 +50,6 @@ public class SubjectCanonicalizationFlowDescriptor extends AbstractIdentifiableI
/** Predicate that must be true for this flow to be usable for a given request. */
@Nonnull private Predicate<ProfileRequestContext> activationCondition;
-
- /** Optional "inline" c14n implementation to execute without running a subflow. */
- @Nullable private SubjectCanonicalizer subjectCanonicalizer;
/** Constructor. */
public SubjectCanonicalizationFlowDescriptor() {
@@ -80,6 +77,10 @@ public class SubjectCanonicalizationFlowDescriptor extends AbstractIdentifiableI
*/
public void setFlowId(@Nullable final String id) {
checkSetterPreconditions();
+
+ Constraint.isFalse(this instanceof SubjectCanonicalizer,
+ "Flow ID cannot be set on inline c14n implementation.");
+
flowId = StringSupport.trimOrNull(id);
if (id != null) {
Constraint.isFalse(flowId.startsWith("c14n/"), "Flow ID must begin with c14n/ prefix.");
@@ -96,40 +97,13 @@ public class SubjectCanonicalizationFlowDescriptor extends AbstractIdentifiableI
checkSetterPreconditions();
activationCondition = Constraint.isNotNull(condition, "Activation condition predicate cannot be null");
}
-
- /**
- * Get an "inline" implementation of subject c14n that does not require use of a Spring WebFlow.
- *
- * @return implementation of {@link SubjectCanonicalizer} interface to use
- *
- * @since 5.2.0
- */
- @Nullable public SubjectCanonicalizer getImplementation() {
- return subjectCanonicalizer;
- }
-
- /**
- * Set an "inline" implementation of subject c14n that does not require use of a Spring WebFlow.
- *
- * @param impl implementation of {@link SubjectCanonicalizer} interface to use
- *
- * @since 5.2.0
- */
- public void setImplementation(@Nullable final SubjectCanonicalizer impl) {
- checkSetterPreconditions();
- subjectCanonicalizer = impl;
- }
-
+
/** {@inheritDoc} */
@Override
protected void doInitialize() throws ComponentInitializationException {
super.doInitialize();
- if (subjectCanonicalizer != null) {
- if (flowId != null) {
- throw new ComponentInitializationException("Implementation object and flow ID are mutually exclusive.");
- }
- } else if (flowId == null) {
+ if (flowId == null && !(this instanceof SubjectCanonicalizer)) {
// Backfill flow ID with component ID.
flowId = ensureId();
if (!flowId.startsWith("c14n/")) {
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/SelectSubjectCanonicalizationFlow.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/SelectSubjectCanonicalizationFlow.java
index 45429a9cd..a900eda8d 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/SelectSubjectCanonicalizationFlow.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/SelectSubjectCanonicalizationFlow.java
@@ -87,10 +87,9 @@ public class SelectSubjectCanonicalizationFlow extends AbstractSubjectCanonicali
return;
}
- final SubjectCanonicalizer inline = flow.getImplementation();
- if (inline != null) {
+ if (flow instanceof SubjectCanonicalizer sc) {
log.debug("{} Selecting c14n descriptor {} (Inline implementation)", getLogPrefix(), flow.ensureId());
- final String event = inline.apply(c14nContext);
+ final String event = sc.apply(c14nContext);
if (EventIds.PROCEED_EVENT_ID.equals(event)) {
// This event has to be remapped because of our poor choice of using an empty string to signal proceed.
log.debug("{} Inline c14n implementation {} completed successfully", getLogPrefix(), flow.ensureId());
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 bc6c08051..26c2a7129 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
@@ -52,38 +52,26 @@
<!-- Basic definitioms of post-login c14n flows with property and legacy bean config support. -->
- <bean id="c14n/simple" parent="shibboleth.PostLoginSubjectCanonicalizationFlow">
- <property name="implementation">
- <bean id="SimpleC14N" class="net.shibboleth.idp.authn.impl.SimpleSubjectCanonicalization"
- p:lowercase="#{getObject('shibboleth.c14n.simple.Lowercase') ?: %{idp.c14n.simple.lowercase:false}}"
- p:uppercase="#{getObject('shibboleth.c14n.simple.Uppercase') ?: %{idp.c14n.simple.uppercase:false}}"
- p:trim="#{getObject('shibboleth.c14n.simple.Trim') ?: %{idp.c14n.simple.trim:true}}"
- p:transforms="#{getObject('shibboleth.c14n.simple.Transforms')}" />
- </property>
- </bean>
-
- <bean id="c14n/x500" parent="shibboleth.PostLoginSubjectCanonicalizationFlow">
- <property name="implementation">
- <bean id="X500C14N" 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>
- </bean>
-
- <bean id="c14n/function" parent="shibboleth.PostLoginSubjectCanonicalizationFlow">
- <property name="implementation">
- <bean id="FunctionC14N" class="net.shibboleth.idp.authn.impl.FunctionSubjectCanonicalization"
- p:function="#{getObject('%{idp.c14n.function.Function:DummyC14NFunction}'.trim())}"
- p:lowercase="%{idp.c14n.function.lowercase:false}"
- p:uppercase="%{idp.c14n.function.uppercase:false}"
- p:trim="%{idp.c14n.function.trim:true}"
- p:transforms="#{getObject('shibboleth.c14n.function.Transforms')}" />
- </property>
- </bean>
+ <bean id="c14n/simple" class="net.shibboleth.idp.authn.impl.SimpleSubjectCanonicalization"
+ p:lowercase="#{getObject('shibboleth.c14n.simple.Lowercase') ?: %{idp.c14n.simple.lowercase:false}}"
+ p:uppercase="#{getObject('shibboleth.c14n.simple.Uppercase') ?: %{idp.c14n.simple.uppercase:false}}"
+ p:trim="#{getObject('shibboleth.c14n.simple.Trim') ?: %{idp.c14n.simple.trim:true}}"
+ p:transforms="#{getObject('shibboleth.c14n.simple.Transforms')}" />
+
+ <bean id="c14n/x500" 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')}" />
+
+ <bean id="c14n/function" class="net.shibboleth.idp.authn.impl.FunctionSubjectCanonicalization"
+ p:function="#{getObject('%{idp.c14n.function.Function:DummyC14NFunction}'.trim())}"
+ p:lowercase="%{idp.c14n.function.lowercase:false}"
+ p:uppercase="%{idp.c14n.function.uppercase:false}"
+ p:trim="%{idp.c14n.function.trim:true}"
+ p:transforms="#{getObject('shibboleth.c14n.function.Transforms')}" />
<bean id="DummyC14NFunction" parent="shibboleth.Functions.Constant">
<constructor-arg>
@@ -91,14 +79,7 @@
</constructor-arg>
</bean>
- <bean id="c14n/attribute-sourced" parent="shibboleth.PostLoginSubjectCanonicalizationFlow">
- <property name="implementation">
- <bean id="AttributeSourcedC14N" parent="shibboleth.AttributeSourcedC14N" />
- </property>
- </bean>
-
- <bean id="shibboleth.AttributeSourcedC14N"
- class="net.shibboleth.idp.authn.impl.AttributeSourcedSubjectCanonicalization"
+ <bean id="c14n/attribute-sourced" class="net.shibboleth.idp.authn.impl.AttributeSourcedSubjectCanonicalization"
p:attributeResolver-ref="shibboleth.AttributeResolverService"
p:attributesToResolve-ref="shibboleth.c14n.attribute.AttributesToResolve"
p:attributeSourceIds-ref="shibboleth.c14n.attribute.AttributeSourceIds"
@@ -112,64 +93,44 @@
<!-- The rest are machinery for handling NameIDs, mostly in protocol requests, also for proxying. -->
- <bean id="c14n/SAML2Persistent" parent="shibboleth.AbstractSAML2C14NFlowBean"
+ <bean id="c14n/SAML2Persistent" class="net.shibboleth.idp.saml.nameid.impl.NameIDCanonicalization"
p:formats="#{ {'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'} }">
- <property name="implementation">
- <bean id="NameIDC14N/SAML2Persistent" class="net.shibboleth.idp.saml.nameid.impl.NameIDCanonicalization">
- <property name="decoder">
- <bean class="net.shibboleth.idp.saml.nameid.impl.StoredPersistentIdDecoder"
- p:persistentIdStore="#{getObject('%{idp.persistentId.store:undefined}'.trim())}"
- p:dataSource="#{getObject('%{idp.persistentId.dataSource:undefined}'.trim())}" />
- </property>
- </bean>
+ <property name="decoder">
+ <bean class="net.shibboleth.idp.saml.nameid.impl.StoredPersistentIdDecoder"
+ p:persistentIdStore="#{getObject('%{idp.persistentId.store:undefined}'.trim())}"
+ p:dataSource="#{getObject('%{idp.persistentId.dataSource:undefined}'.trim())}" />
</property>
</bean>
- <bean id="c14n/SAML2Transient" parent="shibboleth.AbstractSAML2C14NFlowBean"
+ <bean id="c14n/SAML2Transient" class="net.shibboleth.idp.saml.nameid.impl.NameIDCanonicalization"
p:formats="#{ {'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'} }">
- <property name="implementation">
- <bean id="NameIDC14N/SAML2Transient" class="net.shibboleth.idp.saml.nameid.impl.NameIDCanonicalization">
- <property name="decoder">
- <bean class="net.shibboleth.idp.saml.nameid.impl.TransientNameIDDecoder"
- p:idStore-ref="shibboleth.StorageService" />
- </property>
- </bean>
+ <property name="decoder">
+ <bean class="net.shibboleth.idp.saml.nameid.impl.TransientNameIDDecoder"
+ p:idStore-ref="shibboleth.StorageService" />
</property>
</bean>
- <bean id="c14n/SAML2CryptoTransient" parent="shibboleth.AbstractSAML2C14NFlowBean"
+ <bean id="c14n/SAML2CryptoTransient" class="net.shibboleth.idp.saml.nameid.impl.NameIDCanonicalization"
p:formats="#{ {'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'} }">
- <property name="implementation">
- <bean id="NameIDC14N/SAML2CryptoTransient" class="net.shibboleth.idp.saml.nameid.impl.NameIDCanonicalization">
- <property name="decoder">
- <bean class="net.shibboleth.idp.saml.nameid.impl.CryptoTransientNameIDDecoder"
- p:dataSealer="#{(environment.containsProperty('idp.sealer.storeResource') or environment.containsProperty('idp.sealer.keyStrategy')) ? getObject('shibboleth.DataSealer') : null}" />
- </property>
- </bean>
+ <property name="decoder">
+ <bean class="net.shibboleth.idp.saml.nameid.impl.CryptoTransientNameIDDecoder"
+ p:dataSealer="#{(environment.containsProperty('idp.sealer.storeResource') or environment.containsProperty('idp.sealer.keyStrategy')) ? getObject('shibboleth.DataSealer') : null}" />
</property>
</bean>
- <bean id="c14n/SAML1Transient" parent="shibboleth.AbstractSAML1C14NFlowBean"
+ <bean id="c14n/SAML1Transient" class="net.shibboleth.idp.saml.nameid.impl.NameIdentifierCanonicalization"
p:formats="#{ {'urn:mace:shibboleth:1.0:nameIdentifier'} }">
- <property name="implementation">
- <bean id="NameIDC14N/SAML1Transient" class="net.shibboleth.idp.saml.nameid.impl.NameIdentifierCanonicalization">
- <property name="decoder">
- <bean class="net.shibboleth.idp.saml.nameid.impl.TransientNameIdentifierDecoder"
- p:idStore-ref="shibboleth.StorageService" />
- </property>
- </bean>
+ <property name="decoder">
+ <bean class="net.shibboleth.idp.saml.nameid.impl.TransientNameIdentifierDecoder"
+ p:idStore-ref="shibboleth.StorageService" />
</property>
</bean>
- <bean id="c14n/SAML1CryptoTransient" parent="shibboleth.AbstractSAML1C14NFlowBean"
+ <bean id="c14n/SAML1CryptoTransient" class="net.shibboleth.idp.saml.nameid.impl.NameIdentifierCanonicalization"
p:formats="#{ {'urn:mace:shibboleth:1.0:nameIdentifier'} }">
- <property name="implementation">
- <bean id="NameIDC14N/SAML1CryptoTransient" class="net.shibboleth.idp.saml.nameid.impl.NameIdentifierCanonicalization">
- <property name="decoder">
- <bean class="net.shibboleth.idp.saml.nameid.impl.CryptoTransientNameIdentifierDecoder"
- p:dataSealer="#{(environment.containsProperty('idp.sealer.storeResource') or environment.containsProperty('idp.sealer.keyStrategy')) ? getObject('shibboleth.DataSealer') : null}" />
- </property>
- </bean>
+ <property name="decoder">
+ <bean class="net.shibboleth.idp.saml.nameid.impl.CryptoTransientNameIdentifierDecoder"
+ p:dataSealer="#{(environment.containsProperty('idp.sealer.storeResource') or environment.containsProperty('idp.sealer.keyStrategy')) ? getObject('shibboleth.DataSealer') : null}" />
</property>
</bean>
@@ -179,14 +140,10 @@
p:uppercase="%{idp.c14n.saml.uppercase:false}"
p:transforms-ref="shibboleth.NameTransforms" />
- <bean id="c14n/SAML2Transform" parent="shibboleth.AbstractSAML2C14NFlowBean"
- p:activationCondition-ref="shibboleth.NameTransformPredicate"
- p:formats-ref="shibboleth.NameTransformFormats">
- <property name="implementation">
- <bean id="NameIDC14N/SAML2Transform" class="net.shibboleth.idp.saml.nameid.impl.NameIDCanonicalization"
- p:decoder="#{getObject('shibboleth.SAML2Transform.NameIDDecoder') ?: getObject('TransformingNameIDDecoder')}" />
- </property>
- </bean>
+ <bean id="c14n/SAML2Transform" class="net.shibboleth.idp.saml.nameid.impl.NameIDCanonicalization"
+ p:activationCondition-ref="shibboleth.NameTransformPredicate"
+ p:formats-ref="shibboleth.NameTransformFormats"
+ p:decoder="#{getObject('shibboleth.SAML2Transform.NameIDDecoder') ?: getObject('TransformingNameIDDecoder')}" />
<bean id="ProxyTransformingNameIDDecoder" lazy-init="true"
class="net.shibboleth.idp.saml.nameid.impl.TransformingNameIDDecoder"
@@ -194,14 +151,10 @@
p:uppercase="%{idp.c14n.saml.proxy.uppercase:false}"
p:transforms-ref="shibboleth.ProxyNameTransforms" />
- <bean id="c14n/SAML2ProxyTransform" parent="shibboleth.AbstractSAML2C14NFlowBean"
- p:activationCondition-ref="shibboleth.ProxyNameTransformPredicate"
- p:formats-ref="shibboleth.ProxyNameTransformFormats">
- <property name="implementation">
- <bean id="NameIDC14N/SAML2ProxyTransform" class="net.shibboleth.idp.saml.nameid.impl.NameIDCanonicalization"
- p:decoder="#{getObject('shibboleth.SAML2ProxyTransform.NameIDDecoder') ?: getObject('ProxyTransformingNameIDDecoder')}" />
- </property>
- </bean>
+ <bean id="c14n/SAML2ProxyTransform" class="net.shibboleth.idp.saml.nameid.impl.NameIDCanonicalization"
+ p:activationCondition-ref="shibboleth.ProxyNameTransformPredicate"
+ p:formats-ref="shibboleth.ProxyNameTransformFormats"
+ p:decoder="#{getObject('shibboleth.SAML2ProxyTransform.NameIDDecoder') ?: getObject('ProxyTransformingNameIDDecoder')}" />
<bean id="TransformingNameIdentifierDecoder" lazy-init="true"
class="net.shibboleth.idp.saml.nameid.impl.TransformingNameIdentifierDecoder"
@@ -209,13 +162,9 @@
p:uppercase="%{idp.c14n.saml.uppercase:false}"
p:transforms-ref="shibboleth.NameTransforms" />
- <bean id="c14n/SAML1Transform" parent="shibboleth.AbstractSAML1C14NFlowBean"
- p:activationCondition-ref="shibboleth.NameTransformPredicate"
- p:formats-ref="shibboleth.NameTransformFormats">
- <property name="implementation">
- <bean id="NameIDC14N/SAML1Transform" class="net.shibboleth.idp.saml.nameid.impl.NameIdentifierCanonicalization"
- p:decoder="#{getObject('shibboleth.SAML1Transform.NameIdentifierDecoder') ?: getObject('TransformingNameIdentifierDecoder')}" />
- </property>
- </bean>
+ <bean id="c14n/SAML1Transform" class="net.shibboleth.idp.saml.nameid.impl.NameIdentifierCanonicalization"
+ p:activationCondition-ref="shibboleth.NameTransformPredicate"
+ p:formats-ref="shibboleth.NameTransformFormats"
+ p:decoder="#{getObject('shibboleth.SAML1Transform.NameIdentifierDecoder') ?: getObject('TransformingNameIdentifierDecoder')}" />
</beans>
diff --git a/idp-saml-api/src/main/java/net/shibboleth/idp/saml/nameid/AbstractNameIDCanonicalizer.java b/idp-saml-api/src/main/java/net/shibboleth/idp/saml/nameid/AbstractNameIDCanonicalizer.java
new file mode 100644
index 000000000..ba6b0ac4a
--- /dev/null
+++ b/idp-saml-api/src/main/java/net/shibboleth/idp/saml/nameid/AbstractNameIDCanonicalizer.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed 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.saml.nameid;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import net.shibboleth.idp.authn.AbstractSubjectCanonicalizer;
+import net.shibboleth.idp.authn.AuthnEventIds;
+import net.shibboleth.idp.authn.SubjectCanonicalizer;
+import net.shibboleth.idp.authn.context.SubjectCanonicalizationContext;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Base class for "inline" implementations of SAML c14n flows.
+ *
+ * @since 5.2.0
+ */
+public abstract class AbstractNameIDCanonicalizer extends NameIDCanonicalizationFlowDescriptor
+ implements SubjectCanonicalizer {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(AbstractSubjectCanonicalizer.class);
+
+ /** Cached log prefix. */
+ @NonnullAfterInit private String logPrefix;
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+
+ logPrefix = "SubjectCanonicalizer " + ensureId() + ":";
+ }
+
+
+ /**
+ * Performs this c14n action's pre-execute step. Default implementation just returns true iff a subject
+ * is set.
+ *
+ * @param c14nContext the current subject canonicalization context
+ *
+ * @return event indicating result of function
+ */
+ @Nullable public String apply(@Nullable final SubjectCanonicalizationContext c14nContext) {
+ checkComponentActive();
+
+ if (c14nContext == null) {
+ return AuthnEventIds.INVALID_SUBJECT_C14N_CTX;
+ }
+
+ if (c14nContext.getSubject() == null) {
+ log.error("{} No Subject found in context", getLogPrefix());
+ return AuthnEventIds.INVALID_SUBJECT_C14N_CTX;
+ }
+
+ return doApply(c14nContext);
+ }
+
+ /**
+ * Performs c14n if possible.
+ *
+ * @param c14nContext the current subject canonicalization context
+ *
+ * @return event indicating result of function
+ */
+ protected abstract @Nullable String doApply(@Nonnull final SubjectCanonicalizationContext c14nContext);
+
+ /**
+ * Return a prefix for logging messages for this component.
+ *
+ * @return a string for insertion at the beginning of any log messages
+ */
+ @NonnullAfterInit protected String getLogPrefix() {
+ return logPrefix;
+ }
+
+}
\ No newline at end of file
diff --git a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/nameid/impl/NameIDCanonicalization.java b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/nameid/impl/NameIDCanonicalization.java
index 4dadff45b..7955c4623 100644
--- a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/nameid/impl/NameIDCanonicalization.java
+++ b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/nameid/impl/NameIDCanonicalization.java
@@ -26,14 +26,12 @@ import org.opensaml.saml.saml2.core.NameIDType;
import org.opensaml.saml.saml2.profile.SAML2ObjectSupport;
import org.slf4j.Logger;
-import net.shibboleth.idp.authn.AbstractSubjectCanonicalizer;
import net.shibboleth.idp.authn.AuthnEventIds;
-import net.shibboleth.idp.authn.SubjectCanonicalizationFlowDescriptor;
import net.shibboleth.idp.authn.SubjectCanonicalizer;
import net.shibboleth.idp.authn.context.SubjectCanonicalizationContext;
import net.shibboleth.idp.saml.authn.principal.NameIDPrincipal;
+import net.shibboleth.idp.saml.nameid.AbstractNameIDCanonicalizer;
import net.shibboleth.idp.saml.nameid.NameDecoderException;
-import net.shibboleth.idp.saml.nameid.NameIDCanonicalizationFlowDescriptor;
import net.shibboleth.idp.saml.nameid.NameIDDecoder;
import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
import net.shibboleth.shared.component.ComponentInitializationException;
@@ -45,7 +43,7 @@ import net.shibboleth.shared.primitive.LoggerFactory;
* into a principal name by searching for one and only one {@link NameIDPrincipal} custom principal,
* using an injected {@link NameIDDecoder} to carry out the process.
*/
-public class NameIDCanonicalization extends AbstractSubjectCanonicalizer {
+public class NameIDCanonicalization extends AbstractNameIDCanonicalizer {
/** Class logger. */
@Nonnull private Logger log = LoggerFactory.getLogger(NameIDCanonicalization.class);
@@ -150,26 +148,9 @@ public class NameIDCanonicalization extends AbstractSubjectCanonicalizer {
private boolean formatMatches(@Nonnull final SubjectCanonicalizationContext c14nContext,
@Nonnull final String format) {
- final SubjectCanonicalizationFlowDescriptor flowDescriptor = c14nContext.getAttemptedFlow();
-
log.debug("{} Attempting to match format '{}'", getLogPrefix(), format);
- if (null == flowDescriptor) {
- log.error("{} Supplied Context has no active FlowDescriptor", getLogPrefix());
- return false;
- }
-
- if (!(flowDescriptor instanceof NameIDCanonicalizationFlowDescriptor)) {
- log.error("{} Flow Descriptor named {} is not appropriate for NameID canonicalization. Use class=\"{}\"",
- getLogPrefix(), flowDescriptor.getId(),
- NameIDCanonicalizationFlowDescriptor.class.getCanonicalName());
- return false;
- }
-
- final NameIDCanonicalizationFlowDescriptor nameIDDescriptor =
- (NameIDCanonicalizationFlowDescriptor) flowDescriptor;
-
- for (final String testFormat : nameIDDescriptor.getFormats()) {
+ for (final String testFormat : getFormats()) {
if (SAML2ObjectSupport.areNameIDFormatsEquivalent(testFormat, format)) {
log.debug("{} Format matches {}", getLogPrefix(), testFormat);
return true;
diff --git a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/nameid/impl/NameIdentifierCanonicalization.java b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/nameid/impl/NameIdentifierCanonicalization.java
index cb6bfd641..daad1f377 100644
--- a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/nameid/impl/NameIdentifierCanonicalization.java
+++ b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/nameid/impl/NameIdentifierCanonicalization.java
@@ -25,14 +25,12 @@ import org.opensaml.saml.saml1.core.NameIdentifier;
import org.opensaml.saml.saml1.profile.SAML1ObjectSupport;
import org.slf4j.Logger;
-import net.shibboleth.idp.authn.AbstractSubjectCanonicalizer;
import net.shibboleth.idp.authn.AuthnEventIds;
-import net.shibboleth.idp.authn.SubjectCanonicalizationFlowDescriptor;
import net.shibboleth.idp.authn.SubjectCanonicalizer;
import net.shibboleth.idp.authn.context.SubjectCanonicalizationContext;
import net.shibboleth.idp.saml.authn.principal.NameIdentifierPrincipal;
+import net.shibboleth.idp.saml.nameid.AbstractNameIDCanonicalizer;
import net.shibboleth.idp.saml.nameid.NameDecoderException;
-import net.shibboleth.idp.saml.nameid.NameIDCanonicalizationFlowDescriptor;
import net.shibboleth.idp.saml.nameid.NameIdentifierDecoder;
import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
import net.shibboleth.shared.component.ComponentInitializationException;
@@ -44,7 +42,7 @@ import net.shibboleth.shared.primitive.LoggerFactory;
* into a principal name by searching for one and only one {@link NameIdentifierPrincipal} custom principal,
* using an injected {@link NameIdentifierDecoder} to carry out the process.
*/
-public class NameIdentifierCanonicalization extends AbstractSubjectCanonicalizer {
+public class NameIdentifierCanonicalization extends AbstractNameIDCanonicalizer {
/** Class logger. */
@Nonnull private final Logger log = LoggerFactory.getLogger(NameIdentifierCanonicalization.class);
@@ -149,26 +147,7 @@ public class NameIdentifierCanonicalization extends AbstractSubjectCanonicalizer
private boolean formatMatches(@Nonnull final SubjectCanonicalizationContext c14nContext,
@Nonnull final String format) {
- final SubjectCanonicalizationFlowDescriptor flowDescriptor = c14nContext.getAttemptedFlow();
-
- log.debug("{} Attempting to match format '{}'", getLogPrefix(), format);
-
- if (null == flowDescriptor) {
- log.error("{} Supplied context has no active FlowDescriptor", getLogPrefix());
- return false;
- }
-
- if (!(flowDescriptor instanceof NameIDCanonicalizationFlowDescriptor)) {
- log.error("{} Flow Descriptor named {} is not appropriate for NameID canonicalization. Use class=\"{}\"",
- getLogPrefix(), flowDescriptor.getId(),
- NameIDCanonicalizationFlowDescriptor.class.getCanonicalName());
- return false;
- }
-
- final NameIDCanonicalizationFlowDescriptor nameIDDescriptor =
- (NameIDCanonicalizationFlowDescriptor) flowDescriptor;
-
- for (final String testFormat : nameIDDescriptor.getFormats()) {
+ for (final String testFormat : getFormats()) {
if (SAML1ObjectSupport.areNameIdentifierFormatsEquivalent(testFormat, format)) {
log.debug("{} Format matches {}", getLogPrefix(), testFormat);
return true;
diff --git a/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/nameid/impl/CryptoTransientNameIDDecoderTest.java b/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/nameid/impl/CryptoTransientNameIDDecoderTest.java
index 17adf6c49..0dfd0d8ef 100644
--- a/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/nameid/impl/CryptoTransientNameIDDecoderTest.java
+++ b/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/nameid/impl/CryptoTransientNameIDDecoderTest.java
@@ -27,7 +27,6 @@ import net.shibboleth.idp.profile.testing.RequestContextBuilder;
import net.shibboleth.idp.saml.authn.principal.NameIDPrincipal;
import net.shibboleth.idp.saml.impl.testing.TestSources;
import net.shibboleth.idp.saml.nameid.NameDecoderException;
-import net.shibboleth.idp.saml.nameid.NameIDCanonicalizationFlowDescriptor;
import net.shibboleth.shared.collection.CollectionSupport;
import net.shibboleth.shared.component.ComponentInitializationException;
import net.shibboleth.shared.security.DataSealer;
@@ -166,13 +165,10 @@ public class CryptoTransientNameIDDecoderTest extends OpenSAMLInitBaseTestCase {
final NameID nameID = generator.generate(prc, generator.getFormat());
assert nameID!=null;
- final NameIDCanonicalizationFlowDescriptor desc = new NameIDCanonicalizationFlowDescriptor();
- desc.setId("c14n/C14NDesc");
- desc.setFormats(CollectionSupport.singleton(generator.getFormat()));
- desc.initialize();
final NameIDCanonicalization canon = new NameIDCanonicalization();
canon.setId("test");
+ canon.setFormats(CollectionSupport.singleton(generator.getFormat()));
canon.setDecoder(decoder);
canon.initialize();
@@ -182,7 +178,7 @@ public class CryptoTransientNameIDDecoderTest extends OpenSAMLInitBaseTestCase {
subject.getPrincipals().add(new NameIDPrincipal(nameID));
scc.setSubject(subject);
- scc.setAttemptedFlow(desc);
+ scc.setAttemptedFlow(canon);
scc.setRequesterId(TestSources.SP_ENTITY_ID);
scc.setResponderId(TestSources.IDP_ENTITY_ID);
diff --git a/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/nameid/impl/CryptoTransientNameIdentifierDecoderTest.java b/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/nameid/impl/CryptoTransientNameIdentifierDecoderTest.java
index adf5323e4..b8078333c 100644
--- a/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/nameid/impl/CryptoTransientNameIdentifierDecoderTest.java
+++ b/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/nameid/impl/CryptoTransientNameIdentifierDecoderTest.java
@@ -23,7 +23,6 @@ import net.shibboleth.idp.authn.context.SubjectContext;
import net.shibboleth.idp.profile.testing.RequestContextBuilder;
import net.shibboleth.idp.saml.authn.principal.NameIdentifierPrincipal;
import net.shibboleth.idp.saml.impl.testing.TestSources;
-import net.shibboleth.idp.saml.nameid.NameIDCanonicalizationFlowDescriptor;
import net.shibboleth.shared.collection.CollectionSupport;
import net.shibboleth.shared.security.DataSealer;
import net.shibboleth.shared.security.impl.BasicKeystoreKeyStrategy;
@@ -102,14 +101,10 @@ public class CryptoTransientNameIdentifierDecoderTest extends OpenSAMLInitBaseTe
final NameIdentifier nameID = generator.generate(prc, generator.getFormat());
assert nameID!=null;
- final NameIDCanonicalizationFlowDescriptor desc = new NameIDCanonicalizationFlowDescriptor();
- desc.setId("c14n/C14NDesc");
- desc.setFormats(CollectionSupport.singleton(generator.getFormat()));
- desc.initialize();
final NameIdentifierCanonicalization canon = new NameIdentifierCanonicalization();
canon.setId("test");
- assert decoder!=null;
+ canon.setFormats(CollectionSupport.singleton(generator.getFormat()));
canon.setDecoder(decoder);
canon.initialize();
@@ -119,7 +114,7 @@ public class CryptoTransientNameIdentifierDecoderTest extends OpenSAMLInitBaseTe
subject.getPrincipals().add(new NameIdentifierPrincipal(nameID));
scc.setSubject(subject);
- scc.setAttemptedFlow(desc);
+ scc.setAttemptedFlow(canon);
scc.setRequesterId(TestSources.SP_ENTITY_ID);
scc.setResponderId(TestSources.IDP_ENTITY_ID);
diff --git a/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/nameid/impl/NameIDCanonicalizationTest.java b/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/nameid/impl/NameIDCanonicalizationTest.java
index 6d9097a02..62c5c2bd2 100644
--- a/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/nameid/impl/NameIDCanonicalizationTest.java
+++ b/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/nameid/impl/NameIDCanonicalizationTest.java
@@ -26,7 +26,6 @@ import net.shibboleth.idp.authn.context.SubjectCanonicalizationContext;
import net.shibboleth.idp.authn.principal.UsernamePrincipal;
import net.shibboleth.idp.saml.authn.principal.NameIDPrincipal;
import net.shibboleth.idp.saml.nameid.NameDecoderException;
-import net.shibboleth.idp.saml.nameid.NameIDCanonicalizationFlowDescriptor;
import net.shibboleth.idp.saml.nameid.NameIDDecoder;
import org.opensaml.core.testing.OpenSAMLInitBaseTestCase;
@@ -50,8 +49,6 @@ public class NameIDCanonicalizationTest extends OpenSAMLInitBaseTestCase {
private SAMLObjectBuilder<NameID> builder;
- private NameIDCanonicalizationFlowDescriptor flowDescriptor;
-
private static final String REQUESTER = "TestRequest";
private static final String RESPONDER = "TestResp";
@@ -69,13 +66,9 @@ public class NameIDCanonicalizationTest extends OpenSAMLInitBaseTestCase {
@BeforeMethod public void setUp() throws Exception {
prc = new ProfileRequestContext();
- flowDescriptor = new NameIDCanonicalizationFlowDescriptor();
- flowDescriptor.setId("c14n/C14NDesc");
- flowDescriptor.setFormats(formats);
- flowDescriptor.initialize();
-
action = new NameIDCanonicalization();
action.setId("test");
+ action.setFormats(formats);
action.setDecoder(new NameIDDecoder() {
public String decode(SubjectCanonicalizationContext scc, NameID nameID) throws NameDecoderException {
if (RESPONDER.equals(scc.getResponderId()) && REQUESTER.equals(scc.getRequesterId())) {
@@ -99,7 +92,7 @@ public class NameIDCanonicalizationTest extends OpenSAMLInitBaseTestCase {
if (responder != null) {
scc.setResponderId(responder);
}
- return scc.setAttemptedFlow(flowDescriptor);
+ return scc.setAttemptedFlow(action);
}
private NameID nameId(String value, String format, String nameQualifier, String nameSPQualifier) {
@@ -118,7 +111,7 @@ public class NameIDCanonicalizationTest extends OpenSAMLInitBaseTestCase {
}
@Test public void testFormatCount() {
- Assert.assertEquals(flowDescriptor.getFormats().size(), 2);
+ Assert.assertEquals(action.getFormats().size(), 2);
}
@Test public void testNoContext() {
diff --git a/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/nameid/impl/NameIdentifierCanonicalizationTest.java b/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/nameid/impl/NameIdentifierCanonicalizationTest.java
index 25e432804..ee5f4cf52 100644
--- a/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/nameid/impl/NameIdentifierCanonicalizationTest.java
+++ b/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/nameid/impl/NameIdentifierCanonicalizationTest.java
@@ -35,7 +35,6 @@ import net.shibboleth.idp.authn.AuthnEventIds;
import net.shibboleth.idp.authn.context.SubjectCanonicalizationContext;
import net.shibboleth.idp.authn.principal.UsernamePrincipal;
import net.shibboleth.idp.saml.authn.principal.NameIdentifierPrincipal;
-import net.shibboleth.idp.saml.nameid.NameIDCanonicalizationFlowDescriptor;
import net.shibboleth.idp.saml.nameid.NameIdentifierDecoder;
import net.shibboleth.shared.annotation.constraint.NotEmpty;
import net.shibboleth.shared.collection.CollectionSupport;
@@ -47,8 +46,6 @@ public class NameIdentifierCanonicalizationTest extends OpenSAMLInitBaseTestCase
private ProfileRequestContext prc;
- private NameIDCanonicalizationFlowDescriptor flowDescriptor;
-
private NameIdentifierCanonicalization action;
private SAMLObjectBuilder<NameIdentifier> builder;
@@ -70,13 +67,9 @@ public class NameIdentifierCanonicalizationTest extends OpenSAMLInitBaseTestCase
@BeforeMethod public void setUp() throws Exception {
prc = new ProfileRequestContext();
- flowDescriptor = new NameIDCanonicalizationFlowDescriptor();
- flowDescriptor.setId("c14n/C14NDesc");
- flowDescriptor.setFormats(formats);
- flowDescriptor.initialize();
-
action = new NameIdentifierCanonicalization();
action.setId("test");
+ action.setFormats(formats);
action.setDecoder(new NameIdentifierDecoder() {
public String decode(@Nonnull SubjectCanonicalizationContext scc, @Nonnull NameIdentifier nameIdentifier) {
if (RESPONDER.equals(scc.getResponderId()) && REQUESTER.equals(scc.getRequesterId())) {
@@ -100,7 +93,7 @@ public class NameIdentifierCanonicalizationTest extends OpenSAMLInitBaseTestCase
if (responder != null) {
scc.setResponderId(responder);
}
- return scc.setAttemptedFlow(flowDescriptor);
+ return scc.setAttemptedFlow(action);
}
@Nonnull private NameIdentifier nameId(String value, String format, String nameQualifier) {
diff --git a/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/nameid/impl/TransientDecoderTest.java b/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/nameid/impl/TransientDecoderTest.java
index 8be3fe313..d1ef6b6a8 100644
--- a/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/nameid/impl/TransientDecoderTest.java
+++ b/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/nameid/impl/TransientDecoderTest.java
@@ -22,7 +22,6 @@ import net.shibboleth.idp.profile.testing.RequestContextBuilder;
import net.shibboleth.idp.saml.authn.principal.NameIDPrincipal;
import net.shibboleth.idp.saml.impl.testing.TestSources;
import net.shibboleth.idp.saml.nameid.NameDecoderException;
-import net.shibboleth.idp.saml.nameid.NameIDCanonicalizationFlowDescriptor;
import net.shibboleth.shared.collection.CollectionSupport;
import net.shibboleth.shared.component.ComponentInitializationException;
@@ -141,11 +140,8 @@ public class TransientDecoderTest extends OpenSAMLInitBaseTestCase {
final NameID nameid = generator.generate(prc, generator.getFormat());
assert nameid!=null;
- final NameIDCanonicalizationFlowDescriptor descriptor = new NameIDCanonicalizationFlowDescriptor();
- descriptor.setFormats(CollectionSupport.singleton(generator.getFormat()));
- descriptor.setId("c14n/NameIdFlowDescriptor");
- descriptor.initialize();
final NameIDCanonicalization canon = new NameIDCanonicalization();
+ canon.setFormats(CollectionSupport.singleton(generator.getFormat()));
final TransientNameIDDecoder decoder = new TransientNameIDDecoder();
decoder.setId("decoder");
@@ -160,7 +156,7 @@ public class TransientDecoderTest extends OpenSAMLInitBaseTestCase {
final Subject subject = new Subject();
subject.getPrincipals().add(new NameIDPrincipal(nameid));
scc.setSubject(subject);
- scc.setAttemptedFlow(descriptor);
+ scc.setAttemptedFlow(canon);
scc.setRequesterId(TestSources.SP_ENTITY_ID);
scc.setResponderId(TestSources.IDP_ENTITY_ID);
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list