[java-idp-oidc] 02/02: JOIDC-128 - Support OAuth authorization requests

Henri Mikkonen henri.mikkonen at iki.fi
Fri Oct 7 06:01:25 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=e852cff5083bb12b52b3133d05ed0a7acd4c6ca6

commit e852cff5083bb12b52b3133d05ed0a7acd4c6ca6
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Fri Oct 7 08:59:46 2022 +0300

    JOIDC-128 - Support OAuth authorization requests
    
    https://shibboleth.atlassian.net/browse/JOIDC-128
    
    Improved flow tests: cover authorize and token flow tests with OAuth cases
    when requested metadata contains resources or not.
---
 .../oidc/op/profile/flow/AbstractOidcFlowTest.java | 21 ++++++++-
 .../oidc/op/profile/flow/AuthorizeFlowTest.java    | 19 +++++++-
 .../plugin/oidc/op/profile/flow/TokenFlowTest.java | 52 +++++++++++++++++-----
 3 files changed, 80 insertions(+), 12 deletions(-)

diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AbstractOidcFlowTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AbstractOidcFlowTest.java
index 9396dd01..fa2b45f7 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AbstractOidcFlowTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AbstractOidcFlowTest.java
@@ -184,6 +184,13 @@ public abstract class AbstractOidcFlowTest extends AbstractFlowTest {
                 null, null, redirectUri);
     }
 
+    protected void storeMetadata(final StorageService storageService, final String clientId, final String secret,
+            final Scope scope, final boolean addResources, final String... redirectUri) throws IOException {
+        storeMetadata(storageService, clientId, secret, scope, null, null, null,
+                ClientAuthenticationMethod.CLIENT_SECRET_BASIC,
+                null, null, addResources, redirectUri);
+    }
+
 // Checkstyle: ParameterNumber OFF    
     protected void storeMetadata(final StorageService storageService, final String clientId, final String secret,
             final Scope scope, final JWSAlgorithm tokenEndpointSigAlg,
@@ -213,6 +220,15 @@ public abstract class AbstractOidcFlowTest extends AbstractFlowTest {
             final EncryptionMethod encMethod, final ClientAuthenticationMethod tokenEndpointMethod,
             final JWSAlgorithm userInfoSigAlg, final RSAPublicKey publicKey, final String... redirectUri)
                     throws IOException {
+        storeMetadata(storageService, clientId, secret, scope, tokenEndpointSigAlg, tokenEncAlg, encMethod,
+                tokenEndpointMethod, userInfoSigAlg, publicKey, true, redirectUri);
+    }
+    protected void storeMetadata(final StorageService storageService, final String clientId, final String secret,
+            final Scope scope, final JWSAlgorithm tokenEndpointSigAlg, final JWEAlgorithm tokenEncAlg,
+            final EncryptionMethod encMethod, final ClientAuthenticationMethod tokenEndpointMethod,
+            final JWSAlgorithm userInfoSigAlg, final RSAPublicKey publicKey,final boolean addResources,
+            final String... redirectUri)
+                    throws IOException {
         final OIDCClientMetadata metadata = new OIDCClientMetadata();
         metadata.setGrantTypes(new HashSet<GrantType>(List.of(GrantType.AUTHORIZATION_CODE,
                 GrantType.REFRESH_TOKEN, GrantType.CLIENT_CREDENTIALS)));
@@ -243,7 +259,10 @@ public abstract class AbstractOidcFlowTest extends AbstractFlowTest {
         metadata.setIDTokenJWEEnc(encMethod);
         metadata.setTokenEndpointAuthMethod(tokenEndpointMethod);
         metadata.setUserInfoJWSAlg(userInfoSigAlg);
-        metadata.setCustomField("audience", List.of("https://rp.example.org", "https://rp2.example.org", "https://resource.example.org"));
+        if (addResources) {
+            metadata.setCustomField("audience", List.of("https://rp.example.org", "https://rp2.example.org",
+                    "https://resource.example.org"));
+        }
         final OIDCClientInformation information;
         if (publicKey == null) {
             information = new OIDCClientInformation(new ClientID(clientId), new Date(),
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AuthorizeFlowTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AuthorizeFlowTest.java
index fbc73fec..8f515527 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AuthorizeFlowTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AuthorizeFlowTest.java
@@ -157,7 +157,7 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
     }
 
     @Test
-    public void testWithAuthorizationCodeFlowNoOpenid() throws IOException, SessionException {
+    public void testWithAuthorizationCodeFlowNoOpenidMetadataContainsResource() throws IOException, SessionException {
         request.setMethod("GET");
         setRequestParameters(List.of(new Pair<>("client_id", "mockClientId"),
                 new Pair<>("response_type", "code"),
@@ -176,6 +176,23 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
         Assert.assertNull(successResponse.getIssuer());
     }
 
+    @Test
+    public void testWithAuthorizationCodeFlowNoOpenidMetadataNotContainingResource() throws IOException, SessionException {
+        request.setMethod("GET");
+        setRequestParameters(List.of(new Pair<>("client_id", "mockClientId"),
+                new Pair<>("response_type", "code"),
+                new Pair<>("scope", "profile"),
+                new Pair<>("redirect_uri", redirectUri)));
+        storeMetadata(storageService, clientId, clientSecret, scope, false, redirectUri);
+
+        initializeThreadLocals();
+
+        final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+        assertErrorCode(result, "invalid_request");
+        assertErrorDescriptionContains(result, "InvalidTarget");
+        assertErrorResponseWithNoIssuer(result);
+    }
+
     @Test
     public void testWithAuthorizationCodeFlowNoRedirectURI() throws IOException, SessionException {
         request.setMethod("GET");
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/TokenFlowTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/TokenFlowTest.java
index 277a9c30..b92ab2b1 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/TokenFlowTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/TokenFlowTest.java
@@ -63,6 +63,7 @@ import net.shibboleth.idp.plugin.oidc.op.token.support.AccessTokenClaimsSet;
 import net.shibboleth.idp.plugin.oidc.op.token.support.AuthorizeCodeClaimsSet;
 import net.shibboleth.idp.plugin.oidc.op.token.support.RefreshTokenClaimsSet;
 import net.shibboleth.idp.plugin.oidc.op.token.support.TokenClaimsSet;
+import net.shibboleth.oidc.profile.core.OidcError;
 import net.shibboleth.utilities.java.support.collection.Pair;
 import net.shibboleth.utilities.java.support.security.DataSealerException;
 import net.shibboleth.utilities.java.support.security.impl.SecureRandomIdentifierGenerationStrategy;
@@ -148,16 +149,23 @@ public class TokenFlowTest extends AbstractOidcClientAuthenticationFlowTest {
         assertErrorCode(result, OAuth2Error.INVALID_GRANT_CODE);
     }
 
-    /**
-     * TODO: This test "fails" now because it's honoring a non-OIDC request by assuming there has to be
-     * a requested and allowed audience/resource. The original success outcome was an anomaly due to the
-     * original grant handling not supporting the audience notion.
-     */
-    @Test(enabled=false)
-    public void testNoScopes() throws Exception {
+    @Test
+    public void testNoScopesRegisteredWithOpenidScopeRequested() throws Exception {
+        setHttpFormRequest("POST",
+                createRequestParameters(redirectUri, "authorization_code",
+                        buildAuthorizationCode(clientId, null, scope.toString()), clientId));
+        storeMetadata(storageService, clientId, clientSecret, null);
+        setBasicAuth(clientId, clientSecret);
+        storeConsent(storageService, "jdoe", clientId, "mail");
+        final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+        assertErrorCode(result, "invalid_request");
+    }
+
+    @Test
+    public void testNoScopesRegisteredWithoutOpenidScopeRequestedResourcesInMetadata() throws Exception {
         setHttpFormRequest("POST",
                 createRequestParameters(redirectUri, "authorization_code",
-                        buildAuthorizationCode(clientId), clientId));
+                        buildAuthorizationCode(clientId, null, "profile"), clientId));
         storeMetadata(storageService, clientId, clientSecret, null);
         setBasicAuth(clientId, clientSecret);
         storeConsent(storageService, "jdoe", clientId, "mail");
@@ -165,7 +173,19 @@ public class TokenFlowTest extends AbstractOidcClientAuthenticationFlowTest {
         final AccessTokenResponse response = parseSuccessResponse(result, AccessTokenResponse.class);
         Assert.assertNotNull(response.getTokens().getAccessToken());
     }
-    
+
+    @Test
+    public void testNoScopesRegisteredWithoutOpenidScopeRequestedNoResourcesInMetadata() throws Exception {
+        setHttpFormRequest("POST",
+                createRequestParameters(redirectUri, "authorization_code",
+                        buildAuthorizationCode(clientId, null, "profile"), clientId));
+        storeMetadata(storageService, clientId, clientSecret, null, false);
+        setBasicAuth(clientId, clientSecret);
+        storeConsent(storageService, "jdoe", clientId, "mail");
+        final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+        assertErrorCode(result, OidcError.INVALID_TARGET_CODE);
+    }
+
     protected void initializeGrantAndRequest(final String clientId, final Map<String, String> requestParameters)
             throws IOException {
         initializeGrantAndRequest(clientId, requestParameters, true, null);
@@ -422,12 +442,24 @@ public class TokenFlowTest extends AbstractOidcClientAuthenticationFlowTest {
         return buildAuthorizationCode(clientId, verifier, null, null, null);
     }
 
+    protected String buildAuthorizationCode(final String clientId, final String verifier, final String scope)
+            throws Exception {
+        return buildAuthorizationCode(clientId, verifier, null, null, null, scope);
+    }
+
     protected String buildAuthorizationCode(final String clientId, final String verifier,
             final JSONObject deliveryClaims, final JSONObject deliveryClaimsIDToken,
             final JSONObject deliveryClaimsUserInfo) throws Exception {
+        return buildAuthorizationCode(clientId, verifier, deliveryClaims, deliveryClaimsIDToken,
+                deliveryClaimsUserInfo, "openid profile email offline_access");
+    }
+
+    protected String buildAuthorizationCode(final String clientId, final String verifier,
+            final JSONObject deliveryClaims, final JSONObject deliveryClaimsIDToken,
+            final JSONObject deliveryClaimsUserInfo, final String scope) throws Exception {
         return ValidateGrantTest.buildAuthorizationCode(clientId, "https://op.example.org", "jdoe", "mock",
                 redirectUri, verifier, deliveryClaims, deliveryClaimsIDToken, deliveryClaimsUserInfo, 
-                "openid profile email offline_access").toString();
+                scope).toString();
     }
 
     protected String buildAuthorizationCodeWithSid(final String clientId, final String verifier,

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


More information about the commits mailing list