[java-identity-provider] branch main updated: IDP-2407 - Add NameID decoding to SAML login flow
Scott Cantor
cantor.2 at osu.edu
Wed Sep 24 20:57:58 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=b06cbd65306b1334bbf82e435ab03f09423c4d8c
The following commit(s) were added to refs/heads/main by this push:
new b06cbd653 IDP-2407 - Add NameID decoding to SAML login flow
b06cbd653 is described below
commit b06cbd65306b1334bbf82e435ab03f09423c4d8c
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Wed Sep 24 16:57:08 2025 -0400
IDP-2407 - Add NameID decoding to SAML login flow
https://shibboleth.atlassian.net/browse/IDP-2407
Added new property off by default, but shipped true.
---
.../idp/flows/authn/saml-authn-beans.xml | 1 +
.../idp/module/conf/authn/authn.properties | 2 +
.../profile/impl/ValidateSAMLAuthentication.java | 72 +++++++++++++++++++++-
3 files changed, 72 insertions(+), 3 deletions(-)
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/saml-authn-beans.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/saml-authn-beans.xml
index ddb6515e7..4e60153d2 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/saml-authn-beans.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/saml-authn-beans.xml
@@ -458,6 +458,7 @@
p:addDefaultPrincipals="#{getObject('shibboleth.authn.SAML.addDefaultPrincipals') ?: %{idp.authn.SAML.addDefaultPrincipals:false}}"
p:resultCachingPredicate="#{getObject('shibboleth.authn.SAML.resultCachingPredicate')}"
p:attributeExtractionStrategy="#{getObject('shibboleth.authn.SAML.attributeExtractionStrategy')}"
+ p:decodeNameID="%{idp.authn.SAML.decodeNameID:false}"
p:loggedAttributeId="%{idp.authn.SAML.loggedAttributeId:}" />
<bean id="UsableC14NFlows" parent="shibboleth.CommaDelimStringArray" c:_0="%{idp.authn.SAML.c14n.flows:}" />
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/authn/authn.properties b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/authn/authn.properties
index 018ed29f6..5c7302309 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/authn/authn.properties
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/authn/authn.properties
@@ -224,6 +224,8 @@ idp.authn.IPAddress.supportedPrincipals = \
# Fall through to discovery via discoveryRequired property
#idp.authn.SAML.proxyEntityID = https://idp.example.org/idp/shibboleth
#idp.authn.SAML.discoveryRequired = true
+# Apply registry rules to decode NameID(s)
+idp.authn.SAML.decodeNameID = true
# Optionally specify list of c14n beans to apply
#idp.authn.SAML.c14n.flows =
# Generally left false with bidirectional mappings in
diff --git a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/impl/ValidateSAMLAuthentication.java b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/impl/ValidateSAMLAuthentication.java
index e07cb5ef5..ecf6a8341 100644
--- a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/impl/ValidateSAMLAuthentication.java
+++ b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/impl/ValidateSAMLAuthentication.java
@@ -128,6 +128,9 @@ public class ValidateSAMLAuthentication extends AbstractValidationAction {
/** Pluggable strategy function for generalized extraction of data. */
@Nullable private Function<ProfileRequestContext,Collection<IdPAttribute>> attributeExtractionStrategy;
+ /** Whether to apply transcoder registry to NameID elements. */
+ private boolean decodeNameID;
+
/** An IdPAttribute ID to log as a "name" in place of the NameID for "info" purposes. */
@Nullable @NotEmpty private String loggedAttributeId;
@@ -208,7 +211,22 @@ public class ValidateSAMLAuthentication extends AbstractValidationAction {
}
/**
- * An attribute ID to pull a "name" from for logging purposes.
+ * Sets whether to apply the {@link AttributeTranscoderRegistry} to any {@link NameID} elements in
+ * the assertion(s).
+ *
+ * <p>Defaults to false mainly for backward compatibility.</p>
+ *
+ * @param flag flag to set
+ *
+ * @since 5.2.0
+ */
+ public void setDecodeNameID(final boolean flag) {
+ checkSetterPreconditions();
+ decodeNameID = flag;
+ }
+
+ /**
+ * Set an attribute ID to pull a "name" from for logging purposes.
*
* @param id attribute ID
*
@@ -478,8 +496,9 @@ public class ValidateSAMLAuthentication extends AbstractValidationAction {
return proxied;
}
+// Checkstyle: CyclomaticComplexity OFF
/**
- * Process the inbound SAML Attributes.
+ * Process the inbound SAML Attributes and optionally NameID(s).
*
* @param profileRequestContext current profile request context
*/
@@ -498,6 +517,19 @@ public class ValidateSAMLAuthentication extends AbstractValidationAction {
final Response response = (Response) imc.getMessage();
assert response != null;
for (final Assertion assertion : response.getAssertions()) {
+ if (decodeNameID) {
+ final var subject = assertion.getSubject();
+ if (subject != null) {
+ final NameID nameid = subject.getNameID();
+ if (nameid != null) {
+ try {
+ decodeNameID(component.getComponent(), profileRequestContext, nameid, mapped);
+ } catch (final AttributeDecodingException e) {
+ log.error("{} Error decoding inbound NameID", getLogPrefix(), e);
+ }
+ }
+ }
+ }
for (final AttributeStatement statement : assertion.getAttributeStatements()) {
for (final Attribute designator : statement.getAttributes()) {
assert designator!=null;
@@ -527,6 +559,8 @@ public class ValidateSAMLAuthentication extends AbstractValidationAction {
filterAttributes(profileRequestContext);
}
}
+// Checkstyle: CyclomaticComplexity ON
+
/**
* Access the registry of transcoding rules to decode the input {@link Attribute}.
@@ -545,7 +579,7 @@ public class ValidateSAMLAuthentication extends AbstractValidationAction {
final Collection<TranscodingRule> transcodingRules = registry.getTranscodingRules(input);
if (transcodingRules.isEmpty()) {
log.debug("{} No transcoding rule for Attribute (Name '{}', NameFormat: '{}')", getLogPrefix(),
- input.getName(), input.getNameFormat() != null ? input.getNameFormat() : Attribute.UNSPECIFIED);
+ input.getName(), input.getNameFormat());
return;
}
@@ -559,6 +593,38 @@ public class ValidateSAMLAuthentication extends AbstractValidationAction {
}
}
+ /**
+ * Access the registry of transcoding rules to decode the input {@link NameID}.
+ *
+ * @param registry registry of transcoding rules
+ * @param profileRequestContext current profile request context
+ * @param input input object
+ * @param results collection to add results to
+ *
+ * @throws AttributeDecodingException if an error occurs or no results were obtained
+ *
+ * @since 5.2.0
+ */
+ private void decodeNameID(@Nonnull final AttributeTranscoderRegistry registry,
+ @Nonnull final ProfileRequestContext profileRequestContext, @Nonnull final NameID input,
+ @Nonnull @Live final Multimap<String,IdPAttribute> results) throws AttributeDecodingException {
+
+ final Collection<TranscodingRule> transcodingRules = registry.getTranscodingRules(input);
+ if (transcodingRules.isEmpty()) {
+ log.debug("{} No transcoding rule for NameID (Format: '{}')", getLogPrefix(), input.getFormat());
+ return;
+ }
+
+ for (final TranscodingRule rule : transcodingRules) {
+ assert rule != null;
+ final AttributeTranscoder<NameID> transcoder = TranscoderSupport.getTranscoder(rule);
+ final IdPAttribute decodedAttribute = transcoder.decode(profileRequestContext, input, rule);
+ if (decodedAttribute != null) {
+ results.put(decodedAttribute.getId(), decodedAttribute);
+ }
+ }
+ }
+
/**
* Check for inbound attributes and apply filtering.
*
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list