[java-identity-provider] branch main updated: IDP-2003 - Allow for NameID within AuthnRequests while proxying
Scott Cantor
cantor.2 at osu.edu
Tue Apr 25 19:51:47 UTC 2023
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=9c6f619ed19ac36582c8c190b9eb24ccb9bc46b6
The following commit(s) were added to refs/heads/main by this push:
new 9c6f619ed IDP-2003 - Allow for NameID within AuthnRequests while proxying
9c6f619ed is described below
commit 9c6f619ed19ac36582c8c190b9eb24ccb9bc46b6
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Apr 25 15:51:44 2023 -0400
IDP-2003 - Allow for NameID within AuthnRequests while proxying
https://shibboleth.atlassian.net/browse/IDP-2003
Added a brute force function hook to produce the NameID to use.
---
.../idp/flows/authn/saml-authn-beans.xml | 3 +-
.../saml/saml2/profile/impl/AddAuthnRequest.java | 59 ++++++++++++++++++++--
.../saml2/profile/impl/AddAuthnRequestTest.java | 45 ++++++++++++++---
3 files changed, 95 insertions(+), 12 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 9535adfd3..021de88a2 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
@@ -154,7 +154,8 @@
class="net.shibboleth.idp.saml.saml2.profile.impl.AddAuthnRequest" scope="prototype"
p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext"
p:overwriteExisting="true"
- p:issuerLookupStrategy-ref="shibboleth.IssuerLookup.Simple">
+ p:issuerLookupStrategy-ref="shibboleth.IssuerLookup.Simple"
+ p:nameIDLookupStrategy="#{getObject('%{idp.authn.SAML.NameIDLookupStrategy:}'.trim())}">
<property name="identifierGeneratorLookupStrategy">
<bean class="net.shibboleth.profile.config.navigate.IdentifierGenerationStrategyLookupFunction"
p:defaultIdentifierGenerationStrategy-ref="shibboleth.DefaultIdentifierGenerationStrategy" />
diff --git a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAuthnRequest.java b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAuthnRequest.java
index ed710014e..37b3a4e02 100644
--- a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAuthnRequest.java
+++ b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAuthnRequest.java
@@ -65,10 +65,12 @@ import org.opensaml.saml.saml2.core.Extensions;
import org.opensaml.saml.saml2.core.IDPEntry;
import org.opensaml.saml.saml2.core.IDPList;
import org.opensaml.saml.saml2.core.Issuer;
+import org.opensaml.saml.saml2.core.NameID;
import org.opensaml.saml.saml2.core.NameIDPolicy;
import org.opensaml.saml.saml2.core.RequestedAuthnContext;
import org.opensaml.saml.saml2.core.RequesterID;
import org.opensaml.saml.saml2.core.Scoping;
+import org.opensaml.saml.saml2.core.Subject;
import org.opensaml.saml.saml2.metadata.RequestedAttribute;
import org.slf4j.Logger;
import net.shibboleth.shared.primitive.LoggerFactory;
@@ -109,6 +111,9 @@ public class AddAuthnRequest extends AbstractAuthenticationAction {
/** Strategy used to obtain the proxied requester context. */
@Nonnull private Function<ProfileRequestContext,ProxiedRequesterContext> proxiedRequesterContextLookupStrategy;
+ /** Optional strategy to populate request with a {@link NameID}. */
+ @Nullable private Function<ProfileRequestContext,NameID> nameIDLookupStrategy;
+
/** The generator to use. */
@NonnullBeforeExec private IdentifierGenerationStrategy idGenerator;
@@ -199,6 +204,19 @@ public class AddAuthnRequest extends AbstractAuthenticationAction {
proxiedRequesterContextLookupStrategy =
Constraint.isNotNull(strategy, "ProxiedRequesterContext lookup strategy cannot be null");
}
+
+ /**
+ * Set optional strategy to derive a {@link NameID} to populate into the {@link AuthnRequest}'s
+ * {@link Subject} element.
+ *
+ * @param strategy lookup strategy
+ *
+ * @since 5.0.0
+ */
+ public void setNameIDLookupStrategy(@Nullable final Function<ProfileRequestContext,NameID> strategy) {
+ checkSetterPreconditions();
+ nameIDLookupStrategy = strategy;
+ }
// Checkstyle: CyclomaticComplexity OFF
/** {@inheritDoc} */
@@ -319,7 +337,7 @@ public class AddAuthnRequest extends AbstractAuthenticationAction {
object.setNameIDPolicy(nip);
- final RequestedAuthnContext rac = getRequestedAuthnContext(profileRequestContext);
+ final RequestedAuthnContext rac = buildRequestedAuthnContext(profileRequestContext);
if (rac != null) {
final AuthnContextComparisonTypeEnumeration operator =
profileConfiguration.getAuthnContextComparison(profileRequestContext);
@@ -329,11 +347,12 @@ public class AddAuthnRequest extends AbstractAuthenticationAction {
}
object.setRequestedAuthnContext(rac);
}
-
+
+ object.setSubject(buildSubject(profileRequestContext));
object.setScoping(buildScoping(profileRequestContext, authenticationContext.getProxyCount(),
authenticationContext.getProxiableAuthorities()));
-
object.setExtensions(buildExtensions(profileRequestContext));
+
final MessageContext omc = profileRequestContext.getOutboundMessageContext();
assert omc != null;
omc.setMessage(object);
@@ -347,7 +366,7 @@ public class AddAuthnRequest extends AbstractAuthenticationAction {
*
* @return the object to include in the request, or null
*/
- @Nullable private RequestedAuthnContext getRequestedAuthnContext(
+ @Nullable private RequestedAuthnContext buildRequestedAuthnContext(
@Nullable final ProfileRequestContext profileRequestContext) {
// RequestedAuthnContext also based on profile configuration.
@@ -411,6 +430,36 @@ public class AddAuthnRequest extends AbstractAuthenticationAction {
return null;
}
+ /**
+ * Build a {@link Subject} element if necessary.
+ *
+ * @param profileRequestContext profile request context
+ *
+ * @return the {@link Subject} element to include
+ *
+ * @since 5.0.0
+ */
+ @Nullable private Subject buildSubject(@Nonnull final ProfileRequestContext profileRequestContext) {
+
+ final NameID nameID = nameIDLookupStrategy != null
+ ? nameIDLookupStrategy.apply(profileRequestContext) : null;
+ if (nameID == null) {
+ return null;
+ }
+
+ final XMLObjectBuilderFactory bf = XMLObjectProviderRegistrySupport.getBuilderFactory();
+ final SAMLObjectBuilder<Subject> subjectBuilder =
+ (SAMLObjectBuilder<Subject>) bf.<Subject>ensureBuilder(Subject.DEFAULT_ELEMENT_NAME);
+
+ final Subject subject = subjectBuilder.buildObject();
+ subject.setNameID(nameID);
+
+ log.debug("{} Populating request with NameID '{}' and Format '{}'", getLogPrefix(),
+ nameID.getValue(), nameID.getFormat());
+
+ return subject;
+ }
+
/**
* Build a {@link Scoping} element, decrementing the proxy count if set.
*
@@ -425,7 +474,7 @@ public class AddAuthnRequest extends AbstractAuthenticationAction {
boolean include = false;
- assert profileConfiguration!=null;
+ assert profileConfiguration != null;
if (profileConfiguration.isIgnoreScoping(profileRequestContext)) {
log.warn("{} Skipping generation of Scoping element in violation of standard", getLogPrefix());
return null;
diff --git a/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAuthnRequestTest.java b/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAuthnRequestTest.java
index 62689dc8d..1c508664f 100644
--- a/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAuthnRequestTest.java
+++ b/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAuthnRequestTest.java
@@ -46,10 +46,12 @@ import org.opensaml.saml.saml2.core.Extensions;
import org.opensaml.saml.saml2.core.IDPEntry;
import org.opensaml.saml.saml2.core.IDPList;
import org.opensaml.saml.saml2.core.Issuer;
+import org.opensaml.saml.saml2.core.NameID;
import org.opensaml.saml.saml2.core.NameIDPolicy;
import org.opensaml.saml.saml2.core.NameIDType;
import org.opensaml.saml.saml2.core.RequestedAuthnContext;
import org.opensaml.saml.saml2.core.Scoping;
+import org.opensaml.saml.saml2.core.Subject;
import org.opensaml.saml.saml2.metadata.RequestedAttribute;
import org.opensaml.xmlsec.config.BasicXMLSecurityConfiguration;
import org.springframework.webflow.execution.Event;
@@ -80,6 +82,7 @@ public class AddAuthnRequestTest extends OpenSAMLInitBaseTestCase {
private ProfileRequestContext prc1,prc2;
private RelyingPartyContext rpc;
private AddAuthnRequest action;
+ private NameID nameID;
/**
* Set up test state.
@@ -103,10 +106,12 @@ public class AddAuthnRequestTest extends OpenSAMLInitBaseTestCase {
rp.initialize();
rpc.setConfiguration(rp);
rpc.setProfileConfig(new BrowserSSOProfileConfiguration());
- BrowserSSOProfileConfiguration bspc = (BrowserSSOProfileConfiguration) rpc.getProfileConfig();
+ final BrowserSSOProfileConfiguration bspc = (BrowserSSOProfileConfiguration) rpc.getProfileConfig();
assert bspc!=null;
bspc.setSecurityConfiguration(new BasicXMLSecurityConfiguration());
+ nameID = null;
+
action = new AddAuthnRequest();
action.setProfileContextLookupStrategy(
new ChildContextLookup<>(ProfileRequestContext.class).compose(
@@ -114,6 +119,7 @@ public class AddAuthnRequestTest extends OpenSAMLInitBaseTestCase {
new WebflowRequestContextProfileRequestContextLookup())));
action.setAuthenticationContextLookupStrategy(new ParentContextLookup<>(AuthenticationContext.class));
action.setIssuerLookupStrategy(new IssuerLookupFunction());
+ action.setNameIDLookupStrategy(prc -> nameID);
action.initialize();
}
@@ -173,6 +179,7 @@ public class AddAuthnRequestTest extends OpenSAMLInitBaseTestCase {
assertTrue(allowCreate != null && allowCreate);
assertNull(request.getRequestedAuthnContext());
+ assertNull(request.getSubject());
final Scoping scoping = request.getScoping();
assert scoping != null;
@@ -204,7 +211,7 @@ public class AddAuthnRequestTest extends OpenSAMLInitBaseTestCase {
assertTrue(passive != null && passive);
omc.setMessage(null);
- BrowserSSOProfileConfiguration bspc = (BrowserSSOProfileConfiguration) rpc.getProfileConfig();
+ final BrowserSSOProfileConfiguration bspc = (BrowserSSOProfileConfiguration) rpc.getProfileConfig();
assert bspc!=null;
bspc.setForceAuthn(false);
@@ -218,7 +225,7 @@ public class AddAuthnRequestTest extends OpenSAMLInitBaseTestCase {
/** Test that the action works with a NameID format set. */
@Test public void testNameIDFormat() {
- BrowserSSOProfileConfiguration bspc = (BrowserSSOProfileConfiguration) rpc.getProfileConfig();
+ final BrowserSSOProfileConfiguration bspc = (BrowserSSOProfileConfiguration) rpc.getProfileConfig();
assert bspc!=null;
bspc.setNameIDFormatPrecedence(
CollectionSupport.listOf(NameIDType.EMAIL, NameIDType.KERBEROS));
@@ -242,7 +249,7 @@ public class AddAuthnRequestTest extends OpenSAMLInitBaseTestCase {
/** Test that the action works with SPNameQualifier set. */
@Test public void testSPNameQualifier() {
- BrowserSSOProfileConfiguration bspc = (BrowserSSOProfileConfiguration) rpc.getProfileConfig();
+ final BrowserSSOProfileConfiguration bspc = (BrowserSSOProfileConfiguration) rpc.getProfileConfig();
assert bspc!=null;
bspc.setSPNameQualifier(ActionTestingSupport.INBOUND_MSG_ISSUER);
@@ -264,7 +271,7 @@ public class AddAuthnRequestTest extends OpenSAMLInitBaseTestCase {
/** Test that the action works with AttributeConsumingrServiceIndex set. */
@Test public void testAttributeIndex() {
- BrowserSSOProfileConfiguration bspc = (BrowserSSOProfileConfiguration) rpc.getProfileConfig();
+ final BrowserSSOProfileConfiguration bspc = (BrowserSSOProfileConfiguration) rpc.getProfileConfig();
assert bspc!=null;
bspc.setAttributeIndex(42);
@@ -294,7 +301,7 @@ public class AddAuthnRequestTest extends OpenSAMLInitBaseTestCase {
attr2.setNameFormat(Attribute.URI_REFERENCE);
attr2.setName("https://attr2.example.org");
- BrowserSSOProfileConfiguration bspc = (BrowserSSOProfileConfiguration) rpc.getProfileConfig();
+ final BrowserSSOProfileConfiguration bspc = (BrowserSSOProfileConfiguration) rpc.getProfileConfig();
assert bspc!=null;
bspc.setRequestedAttributes(CollectionSupport.listOf(attr1, attr2));
@@ -316,6 +323,32 @@ public class AddAuthnRequestTest extends OpenSAMLInitBaseTestCase {
assertEquals(extension.getRequestedAttributes().size(), 2);
}
+ /** Test that the action works with a NameID set. */
+ @Test public void testNameIDForSubject() {
+ final XMLObjectBuilderFactory bf = XMLObjectProviderRegistrySupport.getBuilderFactory();
+ final SAMLObjectBuilder<NameID> nameIDBuilder =
+ (SAMLObjectBuilder<NameID>) bf.<NameID>ensureBuilder(
+ NameID.DEFAULT_ELEMENT_NAME);
+ nameID = nameIDBuilder.buildObject();
+ nameID.setValue("foo");
+
+ final Event event = action.execute(rc);
+ ActionTestingSupport.assertProceedEvent(event);
+ final MessageContext omc = prc2.getOutboundMessageContext();
+ assert omc!=null;
+
+ assertNotNull(omc.getMessage());
+ assertTrue(omc.getMessage() instanceof AuthnRequest);
+
+ final AuthnRequest request = (AuthnRequest) omc.getMessage();
+ assert request!=null;
+ final Subject subject = request.getSubject();
+ assert subject != null;
+ final NameID n = subject.getNameID();
+ assert n != null;
+ assertEquals(n.getValue(), "foo");
+ }
+
/** Test with Scoping element but no count. */
@Test public void testScopingNoCount() {
ac.getProxiableAuthorities().add("foo");
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list