[java-idp-plugin-oidc-rp] branch main updated: JOIDCRP-54 - Arbitrary claims to request

Phil Smart philip.smart at jisc.ac.uk
Tue Feb 13 11:51:15 UTC 2024


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

philsmart pushed a commit to branch main
in repository java-idp-plugin-oidc-rp.

View the commit online:
http://git.shibboleth.net/view/?p=java-idp-plugin-oidc-rp.git;a=commit;h=543cddd39015e23559006fa11347de196eaf83a3

The following commit(s) were added to refs/heads/main by this push:
     new 543cddd  JOIDCRP-54 - Arbitrary claims to request
543cddd is described below

commit 543cddd39015e23559006fa11347de196eaf83a3
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Tue Feb 13 11:51:13 2024 +0000

    JOIDCRP-54 - Arbitrary claims to request
    
     - Add a BiConsumer to the Request Object building step that accepts a
    profile request context and the current claims set under construction.
     - Bean name shibboleth.authn.oidc.rp.CustomRequestObjectClaimsStrategy
    
    https://shibboleth.atlassian.net/browse/JOIDCRP-54
---
 .../authn/oidc/rp/impl/BuildRequestObject.java     | 21 +++++++++++++
 .../oidc-relying-party-authn-beans.xml             |  3 +-
 .../authn/oidc/rp/impl/BuildRequestObjectTest.java | 36 ++++++++++++++++++++++
 3 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/BuildRequestObject.java b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/BuildRequestObject.java
index e3113e9..2fcf11c 100644
--- a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/BuildRequestObject.java
+++ b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/BuildRequestObject.java
@@ -15,6 +15,7 @@
 package net.shibboleth.idp.plugin.authn.oidc.rp.impl;
 
 import java.time.Duration;
+import java.util.function.BiConsumer;
 import java.util.function.Function;
 import java.util.function.Predicate;
 
@@ -80,6 +81,9 @@ public class BuildRequestObject extends AbstractProfileAction {
     /** A hook to allow additional checking of the request object claims after it is built.*/
     @Nonnull private Predicate<ClaimsSet> claimsSetIsValidPredicate;
     
+    /** A strategy hook to add custom claims to the claims set.*/
+    @Nonnull private BiConsumer<ProfileRequestContext, ClaimsSet> customClaimsStrategy;
+    
     /** 
      * Is the request object going to be signed? if so the 'iss' and 'aud' claims will be set.
      * Defaults to always true, as it is permissible that both 'iss' and 'aud' claim can exist in 
@@ -103,6 +107,20 @@ public class BuildRequestObject extends AbstractProfileAction {
                         new OutboundMessageContextLookup()));
         
         relyingPartyContextLookupStrategy = new ChildContextLookup<>(RelyingPartyContext.class);
+        // Create a no-op consumer
+        customClaimsStrategy = (prc, set) -> {};
+    }
+    
+    /**
+     * Set a bi-consumer hook to add custom claims to the request object.
+     * 
+     * @param strategy The custom claims strategy to set.
+     */
+    public void setCustomClaimsStrategy(@Nullable final BiConsumer<ProfileRequestContext, ClaimsSet> strategy) {
+        checkSetterPreconditions();
+        if (strategy != null) {
+            customClaimsStrategy = strategy;
+        }
     }
     
     
@@ -261,6 +279,9 @@ public class BuildRequestObject extends AbstractProfileAction {
             requestObjectClaims.setClaim("acr_values", acrString);
         }
         
+        // Add custom claims from the claims hook
+        customClaimsStrategy.accept(profileRequestContext, requestObjectClaims);
+        
         // Validate the request object
         if (!validateRequestObject(profileRequestContext, requestObjectClaims)) {
             log.error("{} RequestObject claims are not valid", getLogPrefix());
diff --git a/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-beans.xml b/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-beans.xml
index 41491b5..862e58c 100644
--- a/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-beans.xml
+++ b/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-beans.xml
@@ -230,7 +230,8 @@
     <bean id="BuildRequestObject" class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.BuildRequestObject"
         scope="prototype" p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext"
         p:claimsSetIsValidPredicate="#{getObject('shibboleth.authn.oidc.rp.RequestObjectClaimsSetIsValidPredicate')}"
-        p:requestObjectToBeSignedPredicate-ref="SignRequestObjectCondition" />
+        p:requestObjectToBeSignedPredicate-ref="SignRequestObjectCondition" 
+        p:customClaimsStrategy="#{getObject('shibboleth.authn.oidc.rp.CustomRequestObjectClaimsStrategy')}"/>
         
    <bean id="SignRequestObjectCondition" scope="prototype"
         class="net.shibboleth.oidc.profile.config.logic.SignRequestObjectPredicate"
diff --git a/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/BuildRequestObjectTest.java b/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/BuildRequestObjectTest.java
index 397637c..0437e75 100644
--- a/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/BuildRequestObjectTest.java
+++ b/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/BuildRequestObjectTest.java
@@ -118,6 +118,42 @@ public class BuildRequestObjectTest extends AbstractOIDCTest {
         assertTrue(isValidJSON(claims.toJSONString()));
     }
     
+    /**
+     * Build a request object with the correct claims and custom claims.
+     * 
+     * @throws ComponentInitializationException on error.
+     */
+    @Test
+    public void testBuildRequestObject_CustomClaims_Success() throws ComponentInitializationException {
+        
+        action.setCustomClaimsStrategy((prc,set) -> {
+            set.setClaim("custom", "value");
+        });
+        action.initialize();        
+        final Event event = action.execute(src);
+        assertNull(event);
+        final var outboundMsgCtx = getOutboundMessageContextFailIfNull(prc);     
+        final var outboundMsg = outboundMsgCtx.getMessage();
+        assert outboundMsg != null;
+        assertNotNull(outboundMsg);
+        assertNotNull(
+                ((OIDCAuthenticationRequest)outboundMsg).getRequestObjectClaimsSet());
+        final ClaimsSet claims = (((OIDCAuthenticationRequest)outboundMsg).getRequestObjectClaimsSet());
+        assert claims != null;
+        assertEquals(claims.getStringClaim("scope"),"openid");
+        assertEquals(claims.getStringClaim("iss"),"https://rp.example.com");
+        assertEquals(claims.getStringClaim("client_id"),"https://rp.example.com");
+        assertEquals(claims.getStringClaim("response_type"),"code");
+        assertEquals(claims.getNumberClaim("max_age").longValue(),60);
+        assertEquals(claims.getStringClaim("redirect_uri"),"https://rp.example.com/callback");
+        assertNotNull(claims.getStringClaim("nonce"));
+        assertNotNull(claims.getClaim("aud"));
+        assertNotNull(claims.getStringClaim("custom"));
+        assertEquals(claims.getStringClaim("custom"),"value");
+        
+        assertTrue(isValidJSON(claims.toJSONString()));
+    }
+    
     /**
      * Build a request object with the correct set of ACRs.
      * 

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


More information about the commits mailing list