[java-idp-oidc] branch main updated: JOIDC-189 - Authentification with an unregistered OIDC client fails

Henri Mikkonen henri.mikkonen at iki.fi
Wed Jan 3 16:15:16 UTC 2024


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

hjmikkon pushed a commit to branch main
in repository java-idp-oidc.

View the commit online:
http://git.shibboleth.net/view/?p=java-idp-oidc.git;a=commit;h=0259a88068edb2193480eef27de4cf13283c9927

The following commit(s) were added to refs/heads/main by this push:
     new 0259a880 JOIDC-189 - Authentification with an unregistered OIDC client fails
0259a880 is described below

commit 0259a88068edb2193480eef27de4cf13283c9927
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Wed Jan 3 18:12:13 2024 +0200

    JOIDC-189 - Authentification with an unregistered OIDC client fails
    
    https://shibboleth.atlassian.net/browse/JOIDC-189
    
    Populate client ID value from authentication/authorization request into the
    EntityDescriptor's entityID in SAMLMetadataContext, if OIDCMetadadaContext
    is not around. It's a sign of unregistered client. The client ID in the
    request has been already verified against policy at this point.
---
 ...tboundAuthenticationResponseMessageContext.java | 32 +++++++++++++++++++++-
 ...ndAuthenticationResponseMessageContextTest.java | 23 ++++++++++++++++
 2 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/InitializeOutboundAuthenticationResponseMessageContext.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/InitializeOutboundAuthenticationResponseMessageContext.java
index 07e2e488..76833b59 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/InitializeOutboundAuthenticationResponseMessageContext.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/InitializeOutboundAuthenticationResponseMessageContext.java
@@ -14,6 +14,7 @@
 
 package net.shibboleth.idp.plugin.oidc.op.profile.impl;
 
+import net.shibboleth.idp.plugin.oidc.op.profile.context.navigate.DefaultClientIDLookupFunction;
 import net.shibboleth.idp.profile.IdPEventIds;
 import net.shibboleth.oidc.metadata.context.OIDCMetadataContext;
 import net.shibboleth.profile.context.RelyingPartyContext;
@@ -60,6 +61,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.nimbusds.langtag.LangTag;
+import com.nimbusds.oauth2.sdk.id.ClientID;
 import com.nimbusds.openid.connect.sdk.rp.OIDCClientMetadata;
 
 /**
@@ -94,6 +96,11 @@ public class InitializeOutboundAuthenticationResponseMessageContext
      */
     @Nonnull private Function<ProfileRequestContext, SAMLMetadataContext> samlMetadataCtxLookupStrategy;
 
+    /**
+     * Strategy used to fetch the unregistered client ID value associated with a given {@link ProfileRequestContext}.
+     */
+    @Nonnull private Function<ProfileRequestContext, ClientID> unregisteredClientIdLookupStrategy;
+
     /** The OIDC metadata context used as a source for the SAML metadata context. */
     @Nullable private OIDCMetadataContext oidcMetadataCtx;
     
@@ -112,6 +119,8 @@ public class InitializeOutboundAuthenticationResponseMessageContext
         relyingPartyCtxLookupStrategy = new ChildContextLookup<>(RelyingPartyContext.class);
         samlMetadataCtxLookupStrategy = FunctionSupport.compose(new SAMLMetadataContextLookupFunction(),
                 new InboundMessageContextLookup());
+        unregisteredClientIdLookupStrategy = FunctionSupport.compose(new DefaultClientIDLookupFunction(),
+                new InboundMessageContextLookup());
         defaultLanguage = "en";
     }
 
@@ -187,6 +196,19 @@ public class InitializeOutboundAuthenticationResponseMessageContext
                 Constraint.isNotNull(strategy, "SAMLMetadataContext lookup strategy cannot be null");
     }
 
+    /**
+     * Set the strategy used to fetch the unregistered client ID value associated with a given
+     * {@link ProfileRequestContext}.
+     * 
+     * @param strategy strategy used to fetch the unregistered client ID value associated with a given
+     *            {@link ProfileRequestContext}.
+     */
+    public void setUnregisteredClientIdLookupStrategy(
+            @Nonnull final Function<ProfileRequestContext, ClientID> strategy) {
+        ifInitializedThrowUnmodifiabledComponentException();
+
+        unregisteredClientIdLookupStrategy = Constraint.isNotNull(strategy, "ClientID lookup strategy cannot be null");
+    }
     /**
      * Set the default language when it has not been defined in the metadata.
      * 
@@ -236,7 +258,16 @@ public class InitializeOutboundAuthenticationResponseMessageContext
         final SPSSODescriptor spDescriptor = new SPSSODescriptorBuilder().buildObject();
         
         if (oidcMetadataCtx != null) {
+            entityDescriptor.setEntityID(oidcMetadataCtx.getClientInformation().getID().getValue());
             populateEntityDescriptor(entityDescriptor, spDescriptor);
+        } else {
+            final ClientID clientId = unregisteredClientIdLookupStrategy.apply(profileRequestContext);
+            if (clientId == null) {
+                log.error("{} No client ID was resolved for the unregistered client", getLogPrefix());
+                ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+                return;
+            }
+            entityDescriptor.setEntityID(clientId.getValue());
         }
 
         samlContext.setEntityDescriptor(entityDescriptor);
@@ -249,7 +280,6 @@ public class InitializeOutboundAuthenticationResponseMessageContext
 
     protected void populateEntityDescriptor(final EntityDescriptor entityDescriptor,
             final SPSSODescriptor spDescriptor) {
-        entityDescriptor.setEntityID(oidcMetadataCtx.getClientInformation().getID().getValue());
         final OIDCClientMetadata oidcMetadata = oidcMetadataCtx.getClientInformation().getOIDCMetadata();
         final UIInfo uiInfo = new UIInfoBuilder().buildObject();
         for (final LangTag tag : oidcMetadata.getLogoURIEntries().keySet()) {
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/InitializeOutboundAuthenticationResponseMessageContextTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/InitializeOutboundAuthenticationResponseMessageContextTest.java
index 15ee48a4..54f60806 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/InitializeOutboundAuthenticationResponseMessageContextTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/InitializeOutboundAuthenticationResponseMessageContextTest.java
@@ -27,6 +27,7 @@ import java.util.Arrays;
 import java.util.Date;
 
 import org.opensaml.core.xml.XMLObject;
+import org.opensaml.profile.action.EventIds;
 import org.opensaml.profile.context.ProfileRequestContext;
 import org.opensaml.saml.common.messaging.context.SAMLMetadataContext;
 import org.opensaml.saml.ext.saml2mdui.UIInfo;
@@ -78,6 +79,28 @@ public class InitializeOutboundAuthenticationResponseMessageContextTest {
         final Event event = action.execute(requestCtx);
         ActionTestingSupport.assertProceedEvent(event);
         Assert.assertNotNull(prc.getOutboundMessageContext());
+        final SAMLMetadataContext samlContext = new SAMLMetadataContextLookupFunction().apply(prc);
+        Assert.assertEquals(samlContext.getEntityDescriptor().getEntityID(), "clientId");
+    }
+
+    @Test
+    public void testSuccessWithUnregistered() {
+        prc.getInboundMessageContext().removeSubcontext(OIDCMetadataContext.class);
+        final Event event = action.execute(requestCtx);
+        ActionTestingSupport.assertProceedEvent(event);
+        Assert.assertNotNull(prc.getOutboundMessageContext());
+        final SAMLMetadataContext samlContext = new SAMLMetadataContextLookupFunction().apply(prc);
+        Assert.assertEquals(samlContext.getEntityDescriptor().getEntityID(), "s6BhdRkqt3");
+    }
+
+    @Test
+    public void testNoClientIdWithUnregistered() throws ComponentInitializationException {
+        prc.getInboundMessageContext().removeSubcontext(OIDCMetadataContext.class);
+        action = new InitializeOutboundAuthenticationResponseMessageContext();
+        action.setUnregisteredClientIdLookupStrategy(prc -> null);
+        action.initialize();
+        final Event event = action.execute(requestCtx);
+        ActionTestingSupport.assertEvent(event, EventIds.INVALID_PROFILE_CTX);
     }
 
     /** Test that action copes with non existent logo. */

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


More information about the commits mailing list