[java-idp-oidc] branch main updated: JOIDC-231 - Multiple resource parameters cause MessageDecodingException
Henri Mikkonen
henri.mikkonen at iki.fi
Thu Oct 3 10:51:27 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=6eda016b099559f148d666a5ea13a7c5081da8d7
The following commit(s) were added to refs/heads/main by this push:
new 6eda016b JOIDC-231 - Multiple resource parameters cause MessageDecodingException
6eda016b is described below
commit 6eda016b099559f148d666a5ea13a7c5081da8d7
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Thu Oct 3 13:51:05 2024 +0300
JOIDC-231 - Multiple resource parameters cause MessageDecodingException
https://shibboleth.atlassian.net/browse/JOIDC-231
Switched the approach of using custom parameter name for 'resource' into using custom prefix for its values.
The parameter values in authorization/authentication/token requests are now prefixed with 'urn:shibboleth.oidc.op.resource:'
before feeding for Nimbus to be parsed. That makes the values to fulfill the strict URI-requirement. The lookup functions
remove the prefix before returning the parameter value.
---
.../DefaultRequestAudienceLookupFunction.java | 23 ++++++++---
.../TokenRequestAudienceLookupFunction.java | 17 ++++++--
.../decoding/impl/BaseOAuth2RequestDecoder.java | 18 ++++----
.../CustomResourceHttpServletRequestWrapper.java | 15 ++++---
.../impl/OIDCAuthenticationRequestDecoderTest.java | 27 ++++++------
.../decoding/impl/OIDCTokenRequestDecoderTest.java | 35 +++++++++++++---
.../OAuth2AuthorizationRequestDecoderTest.java | 48 ++++++++++++++++------
.../oauth2/profile/impl/ValidateAudienceTest.java | 20 ++++-----
.../oidc/op/profile/flow/AuthorizeFlowTest.java | 4 +-
9 files changed, 139 insertions(+), 68 deletions(-)
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestAudienceLookupFunction.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestAudienceLookupFunction.java
index 5efd1749..2116ec85 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestAudienceLookupFunction.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestAudienceLookupFunction.java
@@ -14,9 +14,11 @@
package net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate;
+import java.net.URI;
import java.text.ParseException;
import java.util.Collections;
import java.util.List;
+import java.util.Objects;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -33,17 +35,18 @@ import net.shibboleth.shared.primitive.LoggerFactory;
/**
* A function that returns resource value of the authorization request.
*
- * The resource value is fetched via custom parameter name {@link #CUSTOM_RESOURCE_PARAM_NAME}. The message decoders
- * switches the incoming resource -parameter names into that. The request objects contain the standard resource
- * parameter name.
+ * The resource value is expected to be prefixed with
+ * {@link DefaultRequestAudienceLookupFunction#CUSTOM_RESOURCE_PARAM_PREFIX}. The authorization request message decoder
+ * switches the incoming resource -parameter values to have that prefix. This function returns the value without the
+ * prefix.
*
* @since 4.2.0
*/
@ThreadSafeAfterInit
public class DefaultRequestAudienceLookupFunction extends AbstractAuthorizationRequestLookupFunction<List<String>> {
- /** Custom name for the resource parameter that allows non-uri values. */
- public static final String CUSTOM_RESOURCE_PARAM_NAME = "shibboleth.oidc.op.resource";
+ /** Custom prefix for the resource parameter values to allow non-uri values. */
+ public static final String CUSTOM_RESOURCE_PARAM_PREFIX = "urn:shibboleth.oidc.op.resource:";
/** Class logger. */
@Nonnull private Logger log = LoggerFactory.getLogger(DefaultRequestAudienceLookupFunction.class);
@@ -71,8 +74,16 @@ public class DefaultRequestAudienceLookupFunction extends AbstractAuthorizationR
return null;
}
+ final List<URI> resources = req.getResources();
+ if (resources == null) {
+ return null;
+ }
return checkRequestObject(req, isRequestObjectFromPar, "resource",
- req.getCustomParameter(CUSTOM_RESOURCE_PARAM_NAME), null);
+ resources.stream()
+ .filter(Objects::nonNull)
+ .map(URI::toString)
+ .map(str -> str.substring(CUSTOM_RESOURCE_PARAM_PREFIX.length()))
+ .toList(), null);
}
}
\ No newline at end of file
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/TokenRequestAudienceLookupFunction.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/TokenRequestAudienceLookupFunction.java
index 9579df08..a5c1e9f2 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/TokenRequestAudienceLookupFunction.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/TokenRequestAudienceLookupFunction.java
@@ -14,7 +14,9 @@
package net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate;
+import java.net.URI;
import java.util.List;
+import java.util.Objects;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -23,9 +25,10 @@ import javax.annotation.concurrent.ThreadSafe;
import com.nimbusds.oauth2.sdk.TokenRequest;
/**
- * A function that returns a copy of requested resource list from a {@link TokenRequest}. The resource value is fetched
- * via custom parameter name {@link DefaultRequestAudienceLookupFunction#CUSTOM_RESOURCE_PARAM_NAME}. The token request
- * message decoder switches the incoming resource -parameter names into that.
+ * A function that returns a copy of requested resource list from a {@link TokenRequest}. The resource value is
+ * expected to be prefixed with the {@link DefaultRequestAudienceLookupFunction#CUSTOM_RESOURCE_PARAM_PREFIX}. The token
+ * request message decoder switches the incoming resource -parameter values to have that prefix. This function returns
+ * the value without the prefix.
*
* @since 4.2.0
*/
@@ -35,7 +38,13 @@ public class TokenRequestAudienceLookupFunction extends AbstractTokenRequestLook
/** {@inheritDoc} */
@Override
@Nullable List<String> doLookup(@Nonnull final TokenRequest req) {
- return req.getCustomParameter(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_NAME);
+ final List<URI> resources = req.getResources();
+ return resources == null ? null :
+ resources.stream()
+ .filter(Objects::nonNull)
+ .map(URI::toString)
+ .map(str -> str.substring(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_PREFIX.length()))
+ .toList();
}
}
\ No newline at end of file
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/decoding/impl/BaseOAuth2RequestDecoder.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/decoding/impl/BaseOAuth2RequestDecoder.java
index 67230735..290a44da 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/decoding/impl/BaseOAuth2RequestDecoder.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/decoding/impl/BaseOAuth2RequestDecoder.java
@@ -135,10 +135,10 @@ public abstract class BaseOAuth2RequestDecoder<T extends Request> extends Abstra
}
/**
- * Switches the 'resource' parameter names in the given HTTP request body into a custom parameter name. This allows
- * us to avoid Nimbus library's control over the values of the parameter.
+ * Switches the 'resource' parameter values in the given HTTP request body to contain a custom parameter prefix.
+ * This allows us to avoid Nimbus library's strict requirement of URI values for the parameter.
*
- * @param httpRequest The HTTP request object where the parameter names are switched
+ * @param httpRequest The HTTP request object where the parameter values are prefixed
*/
protected void switchIntoCustomResource(@Nonnull final HTTPRequest httpRequest) {
final String body = httpRequest.getQuery();
@@ -148,22 +148,22 @@ public abstract class BaseOAuth2RequestDecoder<T extends Request> extends Abstra
}
/**
- * Transforms the 'resource' parameter names in the given input with a custom one defined by {@link
- * DefaultRequestAudienceLookupFunction#CUSTOM_RESOURCE_PARAM_NAME}.
+ * Transforms the 'resource' parameter values in the given input to contain a prefix defined by {@link
+ * DefaultRequestAudienceLookupFunction#CUSTOM_RESOURCE_PARAM_PREFIX}.
*
* @param string the input
- * @return the input with resource parameter names transformed into custom ones.
+ * @return the input with resource parameter values transformed having the custom prefix.
*/
@Nullable public static String transformResourceParameter(@Nullable final String string) {
String input = string;
if (input == null || !input.contains("resource=")) {
return input;
}
- final String customParameterName = DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_NAME;
+ final String customParameterPrefix = DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_PREFIX;
if (input.startsWith("resource=")) {
- input = customParameterName + "=" + input.substring("resource=".length());
+ input = "resource=" + customParameterPrefix + input.substring("resource=".length());
}
- input = input.replace("&resource=", "&" + customParameterName + "=");
+ input = input.replace("&resource=", "&resource=" + customParameterPrefix);
log.debug("Returning modified string {}", input);
return input;
}
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/decoding/impl/CustomResourceHttpServletRequestWrapper.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/decoding/impl/CustomResourceHttpServletRequestWrapper.java
index bca19215..0202a2a5 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/decoding/impl/CustomResourceHttpServletRequestWrapper.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/decoding/impl/CustomResourceHttpServletRequestWrapper.java
@@ -14,6 +14,7 @@
package net.shibboleth.idp.plugin.oidc.op.oauth2.decoding.impl;
+import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;
@@ -24,8 +25,8 @@ import jakarta.servlet.http.HttpServletRequestWrapper;
import net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestAudienceLookupFunction;
/**
- * A custom extension to {@link HttpServletRequestWrapper} overriding the resource parameter with a custom one in the
- * query string (for GET) and parameter map (for POST).
+ * A custom extension to {@link HttpServletRequestWrapper} overriding the resource parameter values with a custom prefix
+ * in the query string (for GET) and parameter map (for POST).
*/
public class CustomResourceHttpServletRequestWrapper extends HttpServletRequestWrapper {
@@ -48,8 +49,12 @@ public class CustomResourceHttpServletRequestWrapper extends HttpServletRequestW
@Override
public Map<String, String[]> getParameterMap() {
return super.getParameterMap().entrySet().stream()
- .collect(Collectors.toMap(entry -> "resource".equals(entry.getKey()) ?
- DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_NAME : entry.getKey(),
- Map.Entry::getValue));
+ .collect(Collectors.toMap(Map.Entry::getKey,
+ entry -> entry.getValue() != null && "resource".equals(entry.getKey())
+ ? Arrays.stream(entry.getValue())
+ .map(str -> DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_PREFIX
+ + str)
+ .toArray(String[]::new)
+ : entry.getValue()));
}
}
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/decoding/impl/OIDCAuthenticationRequestDecoderTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/decoding/impl/OIDCAuthenticationRequestDecoderTest.java
index 6ec49f0d..f3fd8980 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/decoding/impl/OIDCAuthenticationRequestDecoderTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/decoding/impl/OIDCAuthenticationRequestDecoderTest.java
@@ -14,6 +14,7 @@
package net.shibboleth.idp.plugin.oidc.op.decoding.impl;
+import java.net.URI;
import java.net.URISyntaxException;
import java.util.Map;
@@ -81,8 +82,8 @@ public class OIDCAuthenticationRequestDecoderTest {
final ResponseType responseType = request.getResponseType();
assert responseType != null;
Assert.assertEquals(responseType.toString(), ResponseType.Value.CODE.toString());
- Assert.assertTrue(request.getCustomParameter(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_NAME)
- .contains("https://resource.example.org/"));
+ Assert.assertTrue(request.getResources()
+ .contains(new URI(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_PREFIX +("https://resource.example.org/"))));
}
@Test
@@ -99,12 +100,12 @@ public class OIDCAuthenticationRequestDecoderTest {
final ResponseType responseType = request.getResponseType();
assert responseType != null;
Assert.assertEquals(responseType.toString(), ResponseType.Value.CODE.toString());
- Assert.assertTrue(request.getCustomParameter(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_NAME)
- .contains("https://resource.example.org/"));
+ Assert.assertTrue(request.getResources()
+ .contains(new URI(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_PREFIX +("https://resource.example.org/"))));
}
@Test
- public void testRequestDecodingWithNonURIResource() throws MessageDecodingException {
+ public void testRequestDecodingWithNonURIResource() throws MessageDecodingException, URISyntaxException {
httpRequest
.setQueryString("response_type=code&client_id=s6BhdRkqt3&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb&scope=openid%20profile&state=af0ifjsldkj&nonce=n-0S6_WzA2Mj&resource=mockResourceId");
decoder.decode();
@@ -117,12 +118,12 @@ public class OIDCAuthenticationRequestDecoderTest {
final ResponseType responseType = request.getResponseType();
assert responseType != null;
Assert.assertEquals(responseType.toString(), ResponseType.Value.CODE.toString());
- Assert.assertTrue(request.getCustomParameter(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_NAME)
- .contains("mockResourceId"));
+ Assert.assertTrue(request.getResources()
+ .contains(new URI(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_PREFIX + "mockResourceId")));
}
@Test
- public void testRequestDecodingWithNonURIResourceFirst() throws MessageDecodingException {
+ public void testRequestDecodingWithNonURIResourceFirst() throws MessageDecodingException, URISyntaxException {
httpRequest
.setQueryString("resource=mockResourceId&response_type=code&client_id=s6BhdRkqt3&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb&scope=openid%20profile&state=af0ifjsldkj&nonce=n-0S6_WzA2Mj");
decoder.decode();
@@ -135,13 +136,13 @@ public class OIDCAuthenticationRequestDecoderTest {
final ResponseType responseType = request.getResponseType();
assert responseType != null;
Assert.assertEquals(responseType.toString(), ResponseType.Value.CODE.toString());
- Assert.assertTrue(request.getCustomParameter(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_NAME)
- .contains("mockResourceId"));
+ Assert.assertTrue(request.getResources()
+ .contains(new URI(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_PREFIX + "mockResourceId")));
}
@SuppressWarnings("null")
@Test
- public void testPostRequestDecodingWithNonURIResource() throws MessageDecodingException {
+ public void testPostRequestDecodingWithNonURIResource() throws MessageDecodingException, URISyntaxException {
httpRequest.setMethod("POST");
httpRequest.setContentType(ContentType.APPLICATION_URLENCODED.toString());
httpRequest.setParameters(CollectionSupport.copyToMap(Map.of("response_type", "code", "client_id", "s6BhdRkqt3",
@@ -156,8 +157,8 @@ public class OIDCAuthenticationRequestDecoderTest {
final ResponseType responseType = request.getResponseType();
assert responseType != null;
Assert.assertEquals(responseType.toString(), ResponseType.Value.CODE.toString());
- Assert.assertTrue(request.getCustomParameter(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_NAME)
- .contains("mockResourceId"));
+ Assert.assertTrue(request.getResources()
+ .contains(new URI(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_PREFIX + "mockResourceId")));
}
@Test(expectedExceptions = MessageDecodingException.class)
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/decoding/impl/OIDCTokenRequestDecoderTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/decoding/impl/OIDCTokenRequestDecoderTest.java
index 9497899e..cd7605a9 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/decoding/impl/OIDCTokenRequestDecoderTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/decoding/impl/OIDCTokenRequestDecoderTest.java
@@ -15,6 +15,8 @@
package net.shibboleth.idp.plugin.oidc.op.decoding.impl;
import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.util.List;
import java.util.Map;
@@ -82,7 +84,7 @@ public class OIDCTokenRequestDecoderTest {
}
@Test
- public void testRequestDecodingWithUriResource() throws MessageDecodingException, IOException {
+ public void testRequestDecodingWithUriResource() throws MessageDecodingException, IOException, URISyntaxException {
httpRequest.addHeader("Authorization", "Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW");
httpRequest.setContentType("application/x-www-form-urlencoded");
httpRequest.addParameter("grant_type", "authorization_code");
@@ -95,12 +97,12 @@ public class OIDCTokenRequestDecoderTest {
final TokenRequest message = (TokenRequest) messageContext.getMessage();
assert message != null;
Assert.assertEquals(message.getAuthorizationGrant().getType().getValue(), "authorization_code");
- Assert.assertEquals(message.getCustomParameter(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_NAME),
- List.of("https://resource.example.org"));
+ Assert.assertEquals(message.getResources(),
+ List.of(new URI(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_PREFIX + "https://resource.example.org")));
}
@Test
- public void testRequestDecodingWithNonUriResource() throws MessageDecodingException, IOException {
+ public void testRequestDecodingWithNonUriResource() throws MessageDecodingException, IOException, URISyntaxException {
httpRequest.addHeader("Authorization", "Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW");
httpRequest.setContentType("application/x-www-form-urlencoded");
httpRequest.addParameter("grant_type", "authorization_code");
@@ -113,8 +115,29 @@ public class OIDCTokenRequestDecoderTest {
final TokenRequest message = (TokenRequest) messageContext.getMessage();
assert message != null;
Assert.assertEquals(message.getAuthorizationGrant().getType().getValue(), "authorization_code");
- Assert.assertEquals(message.getCustomParameter(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_NAME),
- List.of("resource.example.org"));
+ Assert.assertEquals(message.getResources(),
+ List.of(new URI(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_PREFIX + "resource.example.org")));
+ }
+
+ @Test
+ public void testRequestDecodingWithTwoResources() throws MessageDecodingException, IOException, URISyntaxException {
+ httpRequest.addHeader("Authorization", "Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW");
+ httpRequest.setContentType("application/x-www-form-urlencoded");
+ httpRequest.addParameter("grant_type", "authorization_code");
+ httpRequest.addParameter("code", "SplxlOBeZQQYbYS6WxSbIA");
+ httpRequest.addParameter("redirect_uri", "https://client.example.org/cb");
+ httpRequest.addParameter("resource", "https://resource.example.org", "resource.example.org");
+ decoder.decode();
+ final MessageContext messageContext = decoder.getMessageContext();
+ assert messageContext != null;
+ final TokenRequest message = (TokenRequest) messageContext.getMessage();
+ assert message != null;
+ Assert.assertEquals(message.getAuthorizationGrant().getType().getValue(), "authorization_code");
+ Assert.assertEquals(message.getResources().size(), 2);
+ Assert.assertTrue(message.getResources().contains(
+ new URI(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_PREFIX + "resource.example.org")));
+ Assert.assertTrue(message.getResources().contains(
+ new URI(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_PREFIX + "https://resource.example.org")));
}
@Test
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/oauth2/decoding/impl/OAuth2AuthorizationRequestDecoderTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/oauth2/decoding/impl/OAuth2AuthorizationRequestDecoderTest.java
index b406690d..a5c02604 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/oauth2/decoding/impl/OAuth2AuthorizationRequestDecoderTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/oauth2/decoding/impl/OAuth2AuthorizationRequestDecoderTest.java
@@ -14,6 +14,7 @@
package net.shibboleth.idp.plugin.oidc.op.oauth2.decoding.impl;
+import java.net.URI;
import java.net.URISyntaxException;
import java.util.Map;
@@ -80,8 +81,8 @@ public class OAuth2AuthorizationRequestDecoderTest {
assert messageContext != null;
if (messageContext.getMessage() instanceof AuthorizationRequest authzRequest) {
Assert.assertEquals(authzRequest.getResponseType().toString(), ResponseType.Value.CODE.toString());
- Assert.assertTrue(authzRequest.getCustomParameter(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_NAME)
- .contains("https://resource.example.org/"));
+ Assert.assertTrue(authzRequest.getResources()
+ .contains(new URI(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_PREFIX + "https://resource.example.org/")));
} else {
Assert.fail();
}
@@ -98,15 +99,15 @@ public class OAuth2AuthorizationRequestDecoderTest {
assert messageContext != null;
if (messageContext.getMessage() instanceof AuthorizationRequest authzRequest) {
Assert.assertEquals(authzRequest.getResponseType().toString(), ResponseType.Value.CODE.toString());
- Assert.assertTrue(authzRequest.getCustomParameter(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_NAME)
- .contains("https://resource.example.org/"));
+ Assert.assertTrue(authzRequest.getResources()
+ .contains(new URI(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_PREFIX + "https://resource.example.org/")));
} else {
Assert.fail();
}
}
@Test
- public void testRequestDecodingWithNonURIResource() throws MessageDecodingException {
+ public void testRequestDecodingWithNonURIResource() throws MessageDecodingException, URISyntaxException {
httpRequest
.setQueryString("response_type=code&client_id=s6BhdRkqt3&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb&scope=profile&state=af0ifjsldkj&nonce=n-0S6_WzA2Mj&resource=mockResourceId");
decoder.decode();
@@ -116,15 +117,15 @@ public class OAuth2AuthorizationRequestDecoderTest {
assert messageContext != null;
if (messageContext.getMessage() instanceof AuthorizationRequest authzRequest) {
Assert.assertEquals(authzRequest.getResponseType().toString(), ResponseType.Value.CODE.toString());
- Assert.assertTrue(authzRequest.getCustomParameter(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_NAME)
- .contains("mockResourceId"));
+ Assert.assertTrue(authzRequest.getResources()
+ .contains(new URI(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_PREFIX + "mockResourceId")));
} else {
Assert.fail();
}
}
@Test
- public void testRequestDecodingWithNonURIResourceFirst() throws MessageDecodingException {
+ public void testRequestDecodingWithNonURIResourceFirst() throws MessageDecodingException, URISyntaxException {
httpRequest
.setQueryString("resource=mockResourceId&response_type=code&client_id=s6BhdRkqt3&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb&scope=profile&state=af0ifjsldkj&nonce=n-0S6_WzA2Mj");
decoder.decode();
@@ -134,8 +135,29 @@ public class OAuth2AuthorizationRequestDecoderTest {
assert messageContext != null;
if (messageContext.getMessage() instanceof AuthorizationRequest authzRequest) {
Assert.assertEquals(authzRequest.getResponseType().toString(), ResponseType.Value.CODE.toString());
- Assert.assertTrue(authzRequest.getCustomParameter(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_NAME)
- .contains("mockResourceId"));
+ Assert.assertTrue(authzRequest.getResources()
+ .contains(new URI(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_PREFIX + "mockResourceId")));
+ } else {
+ Assert.fail();
+ }
+ }
+
+ @Test
+ public void testRequestDecodingWithTwoResources() throws MessageDecodingException, URISyntaxException {
+ httpRequest
+ .setQueryString("resource=mockResourceId&response_type=code&client_id=s6BhdRkqt3&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb&scope=profile&state=af0ifjsldkj&nonce=n-0S6_WzA2Mj&resource=https%3A%2F%2Fresource.example.org%2F");
+ decoder.decode();
+ final MessageContext messageContext = decoder.getMessageContext();
+ // We are not testing nimbus itself here, i.e. we are happy to decode
+ // one parameter successfully
+ assert messageContext != null;
+ if (messageContext.getMessage() instanceof AuthorizationRequest authzRequest) {
+ Assert.assertEquals(authzRequest.getResponseType().toString(), ResponseType.Value.CODE.toString());
+ Assert.assertEquals(authzRequest.getResources().size(), 2);
+ Assert.assertTrue(authzRequest.getResources()
+ .contains(new URI(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_PREFIX + "mockResourceId")));
+ Assert.assertTrue(authzRequest.getResources()
+ .contains(new URI(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_PREFIX + "https://resource.example.org/")));
} else {
Assert.fail();
}
@@ -143,7 +165,7 @@ public class OAuth2AuthorizationRequestDecoderTest {
@SuppressWarnings("null")
@Test
- public void testPostRequestDecodingWithNonURIResource() throws MessageDecodingException {
+ public void testPostRequestDecodingWithNonURIResource() throws MessageDecodingException, URISyntaxException {
httpRequest.setMethod("POST");
httpRequest.setContentType(ContentType.APPLICATION_URLENCODED.toString());
httpRequest.setParameters(CollectionSupport.copyToMap(Map.of("response_type", "code", "client_id", "s6BhdRkqt3",
@@ -158,8 +180,8 @@ public class OAuth2AuthorizationRequestDecoderTest {
final ResponseType responseType = request.getResponseType();
assert responseType != null;
Assert.assertEquals(responseType.toString(), ResponseType.Value.CODE.toString());
- Assert.assertTrue(request.getCustomParameter(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_NAME)
- .contains("mockResourceId"));
+ Assert.assertTrue(request.getResources()
+ .contains(new URI(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_PREFIX + "mockResourceId")));
}
@Test(expectedExceptions = MessageDecodingException.class)
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateAudienceTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateAudienceTest.java
index 97f278a8..cf077ca6 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateAudienceTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateAudienceTest.java
@@ -18,7 +18,6 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.time.Instant;
import java.util.List;
-import java.util.Map;
import net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestAudienceLookupFunction;
import net.shibboleth.idp.plugin.oidc.op.profile.impl.BaseOIDCResponseActionTest;
@@ -82,9 +81,8 @@ public class ValidateAudienceTest extends BaseOIDCResponseActionTest {
new ClientSecretBasic(new ClientID("s6BhdRkqt3"), new Secret("foo")),
new ClientCredentialsGrant(),
null,
- null,
- Map.of(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_NAME,
- List.of("https://sp3.example.org"))
+ List.of(new URI(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_PREFIX + "https://sp3.example.org")),
+ null
);
setTokenRequest(req);
@@ -106,9 +104,10 @@ public class ValidateAudienceTest extends BaseOIDCResponseActionTest {
new ClientSecretBasic(new ClientID("s6BhdRkqt3"), new Secret("foo")),
new ClientCredentialsGrant(),
null,
- null,
- Map.of(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_NAME,
- List.of("https://sp.example.org", "https://sp3.example.org", "https://sp2.example.org"))
+ List.of(new URI(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_PREFIX +"https://sp.example.org"),
+ new URI(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_PREFIX +"https://sp3.example.org"),
+ new URI(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_PREFIX +"https://sp2.example.org")),
+ null
);
setTokenRequest(req);
@@ -156,9 +155,8 @@ public class ValidateAudienceTest extends BaseOIDCResponseActionTest {
new ClientSecretBasic(new ClientID("s6BhdRkqt3"), new Secret("foo")),
new AuthorizationCodeGrant(new AuthorizationCode("foo"), new URI("http://localhost")),
null,
- null,
- Map.of(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_NAME,
- List.of("https://sp3.example.org")));
+ List.of(new URI(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_PREFIX + "https://sp3.example.org")),
+ null);
setTokenRequest(req);
final AuthorizeCodeClaimsSet claims = new AuthorizeCodeClaimsSet.Builder()
@@ -194,7 +192,7 @@ public class ValidateAudienceTest extends BaseOIDCResponseActionTest {
new ClientSecretBasic(new ClientID("s6BhdRkqt3"), new Secret("foo")),
new AuthorizationCodeGrant(new AuthorizationCode("foo"), new URI("http://localhost")),
null,
- List.of(new URI("https://sp3.example.org")),
+ List.of(new URI(DefaultRequestAudienceLookupFunction.CUSTOM_RESOURCE_PARAM_PREFIX + "https://sp3.example.org")),
null);
setTokenRequest(req);
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 3a54eff1..8dda7b4b 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
@@ -586,6 +586,7 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
new Pair<>("response_type", "code"),
new Pair<>("scope", "openid profile"),
new Pair<>("redirect_uri", redirectUri),
+ new Pair<>("resource", resource),
new Pair<>("resource", resourceNonUri)));
storeMetadata(storageService, clientId, clientSecret, scope, redirectUri);
@@ -602,8 +603,9 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
Assert.assertNull(successResponse.getIssuer());
final List<String> audience = getAudienceFromAuthorizeCodeClaimsSet(successResponse);
Assert.assertNotNull(audience);
- Assert.assertEquals(audience.size(), 1);
+ Assert.assertEquals(audience.size(), 2);
Assert.assertTrue(audience.contains(resourceNonUri));
+ Assert.assertTrue(audience.contains(resource));
}
@Test
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list