[java-idp-oidc] branch main updated: JOIDC-81 - Profile config flag refreshTokensEnabled not honored by the token flow

Henri Mikkonen henri.mikkonen at iki.fi
Fri Mar 18 07:06:40 UTC 2022


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=fba1281404ef81be558c324711c0860ab26897e4

The following commit(s) were added to refs/heads/main by this push:
     new fba12814 JOIDC-81 - Profile config flag refreshTokensEnabled not honored by the token flow
fba12814 is described below

commit fba1281404ef81be558c324711c0860ab26897e4
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Fri Mar 18 09:05:44 2022 +0200

    JOIDC-81 - Profile config flag refreshTokensEnabled not honored by the token flow
    
    https://shibboleth.atlassian.net/browse/JOIDC-81
    
    Disabled the use of refresh_token grant when the refresh tokens are not enabled in
    the profile configuration.
---
 .../plugin/oidc/op/profile/impl/ValidateGrant.java | 22 ++++++++++++++++++++++
 .../oidc/op/profile/impl/ValidateGrantTest.java    | 22 ++++++++++++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateGrant.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateGrant.java
index 2034acc2..33cf70c2 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateGrant.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateGrant.java
@@ -19,6 +19,7 @@ package net.shibboleth.idp.plugin.oidc.op.profile.impl;
 
 import java.text.ParseException;
 import java.util.function.Function;
+import java.util.function.Predicate;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
@@ -43,6 +44,7 @@ import net.shibboleth.idp.plugin.oidc.op.token.support.RefreshTokenClaimsSet;
 import net.shibboleth.idp.plugin.oidc.op.token.support.TokenClaimsSet;
 import net.shibboleth.idp.profile.IdPEventIds;
 import net.shibboleth.idp.profile.context.RelyingPartyContext;
+import net.shibboleth.oidc.profile.config.logic.RefreshTokensEnabledPredicate;
 import net.shibboleth.oidc.profile.core.OidcEventIds;
 import net.shibboleth.utilities.java.support.annotation.ParameterName;
 import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
@@ -84,6 +86,9 @@ public class ValidateGrant extends AbstractOIDCTokenResponseAction {
      */
     @Nonnull private Function<ProfileRequestContext, RelyingPartyContext> relyingPartyContextLookupStrategy;
 
+    /** Predicate used to indicate whether refresh tokens are enabled. */
+    @Nonnull private Predicate<ProfileRequestContext> refreshTokensEnabledPredicate;
+
     /** The RelyingPartyContext to operate on. */
     @Nullable private RelyingPartyContext rpCtx;
 
@@ -95,6 +100,7 @@ public class ValidateGrant extends AbstractOIDCTokenResponseAction {
     public ValidateGrant(@Nonnull @ParameterName(name = "sealer") final DataSealer sealer) {
         dataSealer = Constraint.isNotNull(sealer, "DataSealer cannot be null");
         relyingPartyContextLookupStrategy = new ChildContextLookup<>(RelyingPartyContext.class);
+        refreshTokensEnabledPredicate = new RefreshTokensEnabledPredicate();
     }
 
     /**
@@ -112,6 +118,17 @@ public class ValidateGrant extends AbstractOIDCTokenResponseAction {
                 Constraint.isNotNull(strategy, "RelyingPartyContext lookup strategy cannot be null");
     }
 
+    /**
+     * Set the predicate used to indicate whether refresh tokens are enabled.
+     *
+     * @param predicate predicate used to indicate whether refresh tokens are enabled.
+     */
+    public void setRefreshTokensEnabledPredicate(@Nonnull final Predicate<ProfileRequestContext> predicate) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+        refreshTokensEnabledPredicate =
+                Constraint.isNotNull(predicate, "Refresh tokens enabled predicate cannot be null");
+    }
     /**
      * Set the replay cache instance to use.
      * 
@@ -194,6 +211,11 @@ public class ValidateGrant extends AbstractOIDCTokenResponseAction {
                 }
             }
         } else if (GrantType.REFRESH_TOKEN.equals(grant.getType())) {
+            if (!refreshTokensEnabledPredicate.test(profileRequestContext)) {
+                log.warn("{} Refresh token grant detected, but not enabled", getLogPrefix());
+                ActionSupport.buildEvent(profileRequestContext, OidcEventIds.INVALID_GRANT);
+                return;
+            }
             final RefreshTokenGrant refreshTokentokenGrant = (RefreshTokenGrant) grant;
             if (refreshTokentokenGrant.getRefreshToken() != null
                     && refreshTokentokenGrant.getRefreshToken().getValue() != null) {
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateGrantTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateGrantTest.java
index e1959bdd..29dca63b 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateGrantTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateGrantTest.java
@@ -36,6 +36,8 @@ import org.opensaml.storage.ReplayCache;
 import org.opensaml.storage.impl.MemoryStorageService;
 import org.testng.Assert;
 import org.testng.annotations.Test;
+
+import com.google.common.base.Predicates;
 import com.nimbusds.oauth2.sdk.AuthorizationCode;
 import com.nimbusds.oauth2.sdk.AuthorizationCodeGrant;
 import com.nimbusds.oauth2.sdk.AuthorizationGrant;
@@ -65,6 +67,10 @@ public class ValidateGrantTest extends BaseOIDCResponseActionTest {
     URI callback;
 
     private void init() throws Exception {
+        init(true);
+    }
+    
+    private void init(boolean refreshTokensEnabled) throws Exception {
         final Instant now = Instant.now();
         acClaims = new AuthorizeCodeClaimsSet.Builder()
                 .setJWTID(idGenerator)
@@ -96,6 +102,11 @@ public class ValidateGrantTest extends BaseOIDCResponseActionTest {
         storageService.initialize();
         replayCache.setStorage(storageService);
         action.setReplayCache(replayCache);
+        if (refreshTokensEnabled) {
+            action.setRefreshTokensEnabledPredicate(Predicates.alwaysTrue());
+        } else {
+            action.setRefreshTokensEnabledPredicate(Predicates.alwaysFalse());
+        }
         action.initialize();
     }
 
@@ -177,6 +188,17 @@ public class ValidateGrantTest extends BaseOIDCResponseActionTest {
         Assert.assertNotNull(arc.getAuthorizationGrantClaimsSet());
     }
 
+    @Test
+    public void testRefreshTokenNotEnabled() throws Exception {
+        init(false);
+        final TokenRequest req = new TokenRequest(callback, new ClientID(clientId), rfGrant);
+        profileRequestCtx.getInboundMessageContext().setMessage(req);
+        ActionTestingSupport.assertEvent(action.execute(requestCtx), OidcEventIds.INVALID_GRANT);
+        final OIDCAuthenticationResponseContext arc =
+                profileRequestCtx.getOutboundMessageContext().getSubcontext(OIDCAuthenticationResponseContext.class);
+        Assert.assertNull(arc.getAuthorizationGrantClaimsSet());
+    }
+
     @Test
     public void testRefreshTokenReplayed() throws Exception {
         init();

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


More information about the commits mailing list