[java-idp-oidc] branch main updated: JOIDC-225 - Relocate and improve lookup functions for request message contents

Henri Mikkonen henri.mikkonen at iki.fi
Tue Oct 1 10:57:29 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=25e8019efb2c7276eb2156299a092426ab2cff29

The following commit(s) were added to refs/heads/main by this push:
     new 25e8019e JOIDC-225 - Relocate and improve lookup functions for request message contents
25e8019e is described below

commit 25e8019efb2c7276eb2156299a092426ab2cff29
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Tue Oct 1 13:57:10 2024 +0300

    JOIDC-225 - Relocate and improve lookup functions for request message contents
    
    https://shibboleth.atlassian.net/browse/JOIDC-225
    
    - Refactored the 'useOnlyRequestObjectPredicate' to exploit whether the request object is built by the PAR endpoint
      - The predicate may be customized via 'idp.oauth2.par.useOnlyRequestObject' and 'idp.oauth2.authorize.useOnlyRequestObject'
---
 ...AbstractAuthorizationRequestLookupFunction.java |  15 +-
 .../DefaultRequestAudienceLookupFunction.java      |   3 +-
 .../DefaultRequestCodeChallengeLookupFunction.java |   2 +-
 ...ltRequestCodeChallengeMethodLookupFunction.java |   3 +-
 .../DefaultRequestDPoPJktLookupFunction.java       |   4 +-
 .../DefaultRequestLoginHintLookupFunction.java     |   2 +-
 .../DefaultRequestMaxAgeLookupFunction.java        |   2 +-
 .../DefaultRequestNonceLookupFunction.java         |   2 +-
 .../DefaultRequestRedirectURILookupFunction.java   |   2 +-
 .../DefaultRequestResponseModeLookupFunction.java  |   3 +-
 .../DefaultRequestResponseTypeLookupFunction.java  |   2 +-
 .../DefaultRequestStateLookupFunction.java         |   2 +-
 .../DefaultRequestedAcrLookupFunction.java         |   2 +-
 .../DefaultRequestedClaimsLookupFunction.java      |   2 +-
 .../DefaultRequestedPromptLookupFunction.java      |   2 +-
 .../DefaultRequestedScopeLookupFunction.java       |   2 +-
 .../DefaultUseOnlyRequestObjectPredicate.java      |  16 +-
 .../pushed-authorization-beans.xml                 |  15 +-
 .../idp/flows/oidc/authorize/authorize-beans.xml   | 161 ++++++++++-----------
 .../oidc/op/profile/flow/AuthorizeFlowTest.java    |  55 ++++++-
 20 files changed, 180 insertions(+), 117 deletions(-)

diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/AbstractAuthorizationRequestLookupFunction.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/AbstractAuthorizationRequestLookupFunction.java
index a73ccc1c..11722d71 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/AbstractAuthorizationRequestLookupFunction.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/AbstractAuthorizationRequestLookupFunction.java
@@ -29,6 +29,7 @@ import com.nimbusds.oauth2.sdk.PushedAuthorizationRequest;
 
 import net.shibboleth.idp.plugin.oidc.op.messaging.context.OIDCAuthenticationResponseContext;
 import net.shibboleth.shared.annotation.constraint.ThreadSafeAfterInit;
+import net.shibboleth.shared.collection.Pair;
 import net.shibboleth.shared.component.AbstractInitializableComponent;
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.primitive.LoggerFactory;
@@ -51,7 +52,7 @@ public abstract class AbstractAuthorizationRequestLookupFunction<T> extends Abst
     @Nonnull private final Class<? extends AuthorizationRequest> messageClass;
 
     /** The predicate to decide if the parameter values may only be set in the request object. */
-    @Nonnull private BiPredicate<AuthorizationRequest, String> useOnlyRequestObjectPredicate;
+    @Nonnull private BiPredicate<Pair<AuthorizationRequest,Boolean>, String> useOnlyRequestObjectPredicate;
 
     /**
      * Constructor.
@@ -75,7 +76,8 @@ public abstract class AbstractAuthorizationRequestLookupFunction<T> extends Abst
      * 
      * @param predicate the predicate to decide if the parameter values may only be set in the request object.
      */
-    public void setUseOnlyRequestObjectPredicate(@Nonnull final BiPredicate<AuthorizationRequest, String> predicate) {
+    public void setUseOnlyRequestObjectPredicate(
+            @Nonnull final BiPredicate<Pair<AuthorizationRequest,Boolean>, String> predicate) {
         checkSetterPreconditions();
         useOnlyRequestObjectPredicate = Constraint.isNotNull(predicate,
                 "Use only request object predicate cannot be null");
@@ -122,7 +124,8 @@ public abstract class AbstractAuthorizationRequestLookupFunction<T> extends Abst
         if (message instanceof PushedAuthorizationRequest pushedAuthorizationRequest) {
             final AuthorizationRequest authorizationRequest = pushedAuthorizationRequest.getAuthorizationRequest();
             assert authorizationRequest != null;
-            return doLookup(authorizationRequest, pushedAuthorizationRequest, localRequestObject, isRequestObjectFromPar);
+            return doLookup(authorizationRequest, pushedAuthorizationRequest, localRequestObject,
+                    isRequestObjectFromPar);
         }
         return doLookup((AuthorizationRequest) message, null, localRequestObject, isRequestObjectFromPar);
     }
@@ -139,8 +142,10 @@ public abstract class AbstractAuthorizationRequestLookupFunction<T> extends Abst
      * @return the parameter value to be used, depending on the authorization request message contents.
      */
     @Nullable protected T checkRequestObject(@Nonnull final AuthorizationRequest authorizationRequest,
-            @Nonnull final String parameterName, @Nullable final T parameterValue, @Nullable T defaultResult) {
-        if (useOnlyRequestObjectPredicate.test(authorizationRequest, parameterName)) {
+            final boolean isRequestObjectFromPar, @Nonnull final String parameterName,
+            @Nullable final T parameterValue, @Nullable T defaultResult) {
+        if (useOnlyRequestObjectPredicate.test(new Pair<>(authorizationRequest,
+                Boolean.valueOf(isRequestObjectFromPar)), parameterName)) {
             log.debug("Ignoring value {}={} from authorization request as request object is defined", parameterName,
                     parameterValue);
             return defaultResult;
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 531851c2..5efd1749 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
@@ -71,7 +71,8 @@ public class DefaultRequestAudienceLookupFunction extends AbstractAuthorizationR
             return null;
         }
 
-        return checkRequestObject(req, "resource", req.getCustomParameter(CUSTOM_RESOURCE_PARAM_NAME), null);
+        return checkRequestObject(req, isRequestObjectFromPar, "resource",
+                req.getCustomParameter(CUSTOM_RESOURCE_PARAM_NAME), 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/DefaultRequestCodeChallengeLookupFunction.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestCodeChallengeLookupFunction.java
index 112eb18b..d8b04887 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestCodeChallengeLookupFunction.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestCodeChallengeLookupFunction.java
@@ -63,7 +63,7 @@ public class DefaultRequestCodeChallengeLookupFunction extends AbstractAuthoriza
             return null;
         }
         return req.getCodeChallenge() == null ? null : 
-            checkRequestObject(req, "code_challenge", req.getCodeChallenge().getValue(), null);
+            checkRequestObject(req, isRequestObjectFromPar, "code_challenge", req.getCodeChallenge().getValue(), 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/DefaultRequestCodeChallengeMethodLookupFunction.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestCodeChallengeMethodLookupFunction.java
index 2a2fb681..abfc51c4 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestCodeChallengeMethodLookupFunction.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestCodeChallengeMethodLookupFunction.java
@@ -65,7 +65,8 @@ public class DefaultRequestCodeChallengeMethodLookupFunction
             return null;
         }
         return req.getCodeChallengeMethod() == null ? null : 
-            checkRequestObject(req, "code_challenge_method", req.getCodeChallengeMethod().getValue(), null);
+            checkRequestObject(req, isRequestObjectFromPar, "code_challenge_method",
+                    req.getCodeChallengeMethod().getValue(), 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/DefaultRequestDPoPJktLookupFunction.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestDPoPJktLookupFunction.java
index 33920b1c..9bd80d8f 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestDPoPJktLookupFunction.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestDPoPJktLookupFunction.java
@@ -62,8 +62,8 @@ public class DefaultRequestDPoPJktLookupFunction extends AbstractAuthorizationRe
             return null;
         }
         return req.getDPoPJWKThumbprintConfirmation() == null ? null :
-            checkRequestObject(req, "dpop_jkt", req.getDPoPJWKThumbprintConfirmation().getValue().toString(),
-                    null);
+            checkRequestObject(req, isRequestObjectFromPar, "dpop_jkt",
+                    req.getDPoPJWKThumbprintConfirmation().getValue().toString(), 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/DefaultRequestLoginHintLookupFunction.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestLoginHintLookupFunction.java
index 14b96ed0..160719a3 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestLoginHintLookupFunction.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestLoginHintLookupFunction.java
@@ -60,6 +60,6 @@ public class DefaultRequestLoginHintLookupFunction extends AbstractAuthenticatio
             log.error("Unable to parse login hint from request object login_hint value");
             return null;
         }
-        return checkRequestObject(req, "login_hint", req.getLoginHint(), null);
+        return checkRequestObject(req, isRequestObjectFromPar, "login_hint", req.getLoginHint(), 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/DefaultRequestMaxAgeLookupFunction.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestMaxAgeLookupFunction.java
index 72376dc9..96b2150b 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestMaxAgeLookupFunction.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestMaxAgeLookupFunction.java
@@ -57,6 +57,6 @@ public class DefaultRequestMaxAgeLookupFunction extends AbstractAuthenticationRe
             return null;
         }
         return req.getMaxAge() == -1 ? null :
-            checkRequestObject(req, "max_age", Duration.ofSeconds(req.getMaxAge()), null);
+            checkRequestObject(req, isRequestObjectFromPar, "max_age", Duration.ofSeconds(req.getMaxAge()), 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/DefaultRequestNonceLookupFunction.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestNonceLookupFunction.java
index 7204b00b..69985e82 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestNonceLookupFunction.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestNonceLookupFunction.java
@@ -62,7 +62,7 @@ public class DefaultRequestNonceLookupFunction extends AbstractAuthenticationReq
             return null;
         }
         if (req.getNonce() != null) {
-            return checkRequestObject(req, "nonce", new Nonce(req.getNonce().getValue()), null);
+            return checkRequestObject(req, isRequestObjectFromPar, "nonce", new Nonce(req.getNonce().getValue()), null);
         }
         return null;
     }
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestRedirectURILookupFunction.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestRedirectURILookupFunction.java
index b188d4d8..23d28d1f 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestRedirectURILookupFunction.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestRedirectURILookupFunction.java
@@ -62,6 +62,6 @@ public class DefaultRequestRedirectURILookupFunction extends AbstractAuthorizati
             log.error("Unable to parse redirect URI from request object redirect_uri value");
             return null;
         }
-        return checkRequestObject(req, "redirect_uri", req.getRedirectionURI(), null);
+        return checkRequestObject(req, isRequestObjectFromPar, "redirect_uri", req.getRedirectionURI(), 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/DefaultRequestResponseModeLookupFunction.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestResponseModeLookupFunction.java
index 83a1af39..c27e7b7d 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestResponseModeLookupFunction.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestResponseModeLookupFunction.java
@@ -66,6 +66,7 @@ public class DefaultRequestResponseModeLookupFunction
         if (req.getResponseMode() == null) {
             return null;
         }
-        return checkRequestObject(req, "response_mode", new ResponseMode(req.getResponseMode().getValue()), null);
+        return checkRequestObject(req, isRequestObjectFromPar, "response_mode",
+                new ResponseMode(req.getResponseMode().getValue()), 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/DefaultRequestResponseTypeLookupFunction.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestResponseTypeLookupFunction.java
index bdcaafaa..60aa5f12 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestResponseTypeLookupFunction.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestResponseTypeLookupFunction.java
@@ -61,6 +61,6 @@ public class DefaultRequestResponseTypeLookupFunction
         if (requestedType != null) {
             result.addAll(requestedType);
         }
-        return checkRequestObject(req, "response_type", result, new ResponseType());
+        return checkRequestObject(req, isRequestObjectFromPar, "response_type", result, new ResponseType());
     }
 }
\ 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/DefaultRequestStateLookupFunction.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestStateLookupFunction.java
index ad7dfb91..e1794e33 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestStateLookupFunction.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestStateLookupFunction.java
@@ -64,6 +64,6 @@ public class DefaultRequestStateLookupFunction extends AbstractAuthorizationRequ
         if (req.getState() == null) {
             return null;
         }
-        return checkRequestObject(req, "state", new State(req.getState().getValue()), null);
+        return checkRequestObject(req, isRequestObjectFromPar, "state", new State(req.getState().getValue()), 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/DefaultRequestedAcrLookupFunction.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestedAcrLookupFunction.java
index 63fb7fb6..f24be19a 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestedAcrLookupFunction.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestedAcrLookupFunction.java
@@ -67,6 +67,6 @@ public class DefaultRequestedAcrLookupFunction extends AbstractAuthenticationReq
         }
         final List<ACR> requestParameterAcr = new ArrayList<ACR>();
         requestParameterAcr.addAll(req.getACRValues());
-        return checkRequestObject(req, "acr_values", requestParameterAcr, null);
+        return checkRequestObject(req, isRequestObjectFromPar, "acr_values", requestParameterAcr, 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/DefaultRequestedClaimsLookupFunction.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestedClaimsLookupFunction.java
index 38f12307..0619e900 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestedClaimsLookupFunction.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestedClaimsLookupFunction.java
@@ -68,7 +68,7 @@ public class DefaultRequestedClaimsLookupFunction
             log.error("unable to parse claims claim {}", e.getMessage());
             return null;
         }
-        return checkRequestObject(req, "claims", req.getOIDCClaims(), null);
+        return checkRequestObject(req, isRequestObjectFromPar, "claims", req.getOIDCClaims(), 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/DefaultRequestedPromptLookupFunction.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestedPromptLookupFunction.java
index 1b0fcda3..bba56e46 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestedPromptLookupFunction.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestedPromptLookupFunction.java
@@ -60,6 +60,6 @@ public class DefaultRequestedPromptLookupFunction extends AbstractAuthorizationR
         }
         final Prompt requestParameterPrompt = new Prompt();
         requestParameterPrompt.addAll(req.getPrompt());
-        return checkRequestObject(req, "prompt", requestParameterPrompt, null);
+        return checkRequestObject(req, isRequestObjectFromPar, "prompt", requestParameterPrompt, 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/DefaultRequestedScopeLookupFunction.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestedScopeLookupFunction.java
index 1adceabd..ba8abe43 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestedScopeLookupFunction.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultRequestedScopeLookupFunction.java
@@ -60,6 +60,6 @@ public class DefaultRequestedScopeLookupFunction extends AbstractAuthorizationRe
         if (requestParameterScope != null) {
             result.addAll(requestParameterScope);
         }
-        return checkRequestObject(req, "scope", result, new Scope());
+        return checkRequestObject(req, isRequestObjectFromPar, "scope", result, new Scope());
     }
 }
\ 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/DefaultUseOnlyRequestObjectPredicate.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultUseOnlyRequestObjectPredicate.java
index aa6f6267..10ea6598 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultUseOnlyRequestObjectPredicate.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/navigate/DefaultUseOnlyRequestObjectPredicate.java
@@ -22,18 +22,28 @@ import javax.annotation.concurrent.ThreadSafe;
 import com.nimbusds.oauth2.sdk.AuthorizationRequest;
 import com.nimbusds.openid.connect.sdk.AuthenticationRequest;
 
+import net.shibboleth.shared.collection.Pair;
+
 /**
  * Default predicate for using only request object parameters if the authorization request (1) contains request object
- * and (2) is not OIDC authentication request.
+ * and (2) is not OIDC authentication request or is provided by the PAR endpoint.
  * 
  * @since 4.2.0
  */
 @ThreadSafe
-public class DefaultUseOnlyRequestObjectPredicate implements BiPredicate<AuthorizationRequest, String> {
+public class DefaultUseOnlyRequestObjectPredicate implements BiPredicate<Pair<AuthorizationRequest,Boolean>, String> {
 
     /** {@inheritDoc} */
     @Override
-    public boolean test(@Nullable final AuthorizationRequest authorizationRequest, @Nullable final String parameter) {
+    public boolean test(@Nullable final Pair<AuthorizationRequest,Boolean> pair, @Nullable final String parameter) {
+        if (pair == null) {
+            return false;
+        }
+        final Boolean isRequestObjectFromPar = pair.getSecond();
+        if (isRequestObjectFromPar != null && isRequestObjectFromPar.booleanValue()) {
+            return true;
+        }
+        final AuthorizationRequest authorizationRequest = pair.getFirst();
         if (authorizationRequest == null) {
             return false;
         }
diff --git a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oauth2/pushed-authorization/pushed-authorization-beans.xml b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oauth2/pushed-authorization/pushed-authorization-beans.xml
index 3dfdf6d1..d7547fc6 100644
--- a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oauth2/pushed-authorization/pushed-authorization-beans.xml
+++ b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oauth2/pushed-authorization/pushed-authorization-beans.xml
@@ -267,7 +267,8 @@
         <ref bean="AudienceClaimsValidator" />
     </util:list>
 
-    <bean id="UseOnlyRequestObjectCondition" parent="shibboleth.BiConditions.Expression" c:expression="#input1 != null and #input1.specifiesRequestObject()" />
+    <bean id="DefaultParUseOnlyRequestObjectCondition" parent="shibboleth.BiConditions.Expression"
+        c:expression="#input1 != null and #input1.getFirst() != null and #input1.getFirst().specifiesRequestObject()" />
 
     <bean id="ValidateRedirectURI" class="net.shibboleth.idp.plugin.oidc.op.oauth2.profile.impl.ValidateRedirectURI"
         scope="prototype"
@@ -275,7 +276,7 @@
         p:unregisteredClientPolicyEnforcer="#{getObject('shibboleth.oidc.UnregisteredClientPolicyEnforcer') ?: getObject('shibboleth.oidc.DefaultUnregisteredClientPolicyEnforcer')}">
         <property name="redirectURILookupStrategy">
             <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestRedirectURILookupFunction"
-                p:useOnlyRequestObjectPredicate-ref="UseOnlyRequestObjectCondition"/>
+                p:useOnlyRequestObjectPredicate-ref="#{'%{idp.oauth2.par.useOnlyRequestObject:DefaultParUseOnlyRequestObjectCondition}'.trim()}"/>
         </property>
     </bean>
 
@@ -284,7 +285,7 @@
         p:unregisteredClientPolicyEnforcer="#{getObject('shibboleth.oidc.UnregisteredClientPolicyEnforcer') ?: getObject('shibboleth.oidc.DefaultUnregisteredClientPolicyEnforcer')}">
         <property name="requestedResponseTypeLookupStrategy">
             <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestResponseTypeLookupFunction"
-                p:useOnlyRequestObjectPredicate-ref="UseOnlyRequestObjectCondition"/>
+                p:useOnlyRequestObjectPredicate-ref="#{'%{idp.oauth2.par.useOnlyRequestObject:DefaultParUseOnlyRequestObjectCondition}'.trim()}"/>
         </property>
         <property name="validResponseTypesLookupStrategy">
             <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultValidResponseTypesLookupFunction"/>            
@@ -295,7 +296,7 @@
         scope="prototype">
         <property name="requestedResponseModeLookupStrategy">
             <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestResponseModeLookupFunction"
-                p:useOnlyRequestObjectPredicate-ref="UseOnlyRequestObjectCondition"/>
+                p:useOnlyRequestObjectPredicate-ref="#{'%{idp.oauth2.par.useOnlyRequestObject:DefaultParUseOnlyRequestObjectCondition}'.trim()}"/>
         </property>
     </bean>
 
@@ -303,11 +304,11 @@
         scope="prototype">
         <property name="codeChallengeLookupStrategy">
             <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestCodeChallengeLookupFunction"
-                p:useOnlyRequestObjectPredicate-ref="UseOnlyRequestObjectCondition"/>
+                p:useOnlyRequestObjectPredicate-ref="#{'%{idp.oauth2.par.useOnlyRequestObject:DefaultParUseOnlyRequestObjectCondition}'.trim()}"/>
         </property>
         <property name="codeChallengeMethodLookupStrategy">
             <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestCodeChallengeMethodLookupFunction"
-                p:useOnlyRequestObjectPredicate-ref="UseOnlyRequestObjectCondition"/>
+                p:useOnlyRequestObjectPredicate-ref="#{'%{idp.oauth2.par.useOnlyRequestObject:DefaultParUseOnlyRequestObjectCondition}'.trim()}"/>
         </property>
     </bean>
 
@@ -315,7 +316,7 @@
         scope="prototype">
         <property name="dpopJktLookupStrategy">
             <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestDPoPJktLookupFunction"
-                p:useOnlyRequestObjectPredicate-ref="UseOnlyRequestObjectCondition"/>
+                p:useOnlyRequestObjectPredicate-ref="#{'%{idp.oauth2.par.useOnlyRequestObject:DefaultParUseOnlyRequestObjectCondition}'.trim()}"/>
         </property>
     </bean>
 
diff --git a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/authorize/authorize-beans.xml b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/authorize/authorize-beans.xml
index 6b9dacd1..a2369b79 100644
--- a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/authorize/authorize-beans.xml
+++ b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/authorize/authorize-beans.xml
@@ -35,25 +35,32 @@
         </constructor-arg>
     </bean>
 
+    <bean id="DefaultUseOnlyRequestObjectCondition"
+        class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultUseOnlyRequestObjectPredicate"/>
+
+    <bean id="DefaultRequestedPromptLookupFunction"
+        class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestedPromptLookupFunction"
+        p:useOnlyRequestObjectPredicate-ref="#{'%{idp.oauth2.authorize.useOnlyRequestObject:DefaultUseOnlyRequestObjectCondition}'.trim()}"/>
+
     <bean id="InitializeAuthenticationContext"
         class="net.shibboleth.idp.plugin.oidc.op.profile.impl.InitializeAuthenticationContext" scope="prototype"
-        p:loginHintLookupStrategy-ref="%{idp.oidc.LoginHintLookupStrategy:DefaultRequestLoginHintLookupFunction}">
-        <property name="promptLookupStrategy">
-            <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestedPromptLookupFunction"/>
-        </property>
+        p:loginHintLookupStrategy-ref="%{idp.oidc.LoginHintLookupStrategy:DefaultRequestLoginHintLookupFunction}"
+        p:promptLookupStrategy-ref="DefaultRequestedPromptLookupFunction">
         <property name="maxAgeLookupStrategy">
-            <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestMaxAgeLookupFunction"/>
+            <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestMaxAgeLookupFunction"
+                p:useOnlyRequestObjectPredicate-ref="#{'%{idp.oauth2.authorize.useOnlyRequestObject:DefaultUseOnlyRequestObjectCondition}'.trim()}"/>
         </property>
     </bean>
 
     <bean id="DefaultRequestLoginHintLookupFunction"
         class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestLoginHintLookupFunction"
-        scope="prototype" />
+        p:useOnlyRequestObjectPredicate-ref="#{'%{idp.oauth2.authorize.useOnlyRequestObject:DefaultUseOnlyRequestObjectCondition}'.trim()}"/>
 
     <bean id="ProcessRequestedAuthnContext"
         class="net.shibboleth.idp.plugin.oidc.op.profile.impl.ProcessRequestedAuthnContext" scope="prototype">
         <property name="acrLookupStrategy">
-            <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestedAcrLookupFunction"/>
+            <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestedAcrLookupFunction"
+                p:useOnlyRequestObjectPredicate-ref="#{'%{idp.oauth2.authorize.useOnlyRequestObject:DefaultUseOnlyRequestObjectCondition}'.trim()}"/>
         </property>
     </bean>
 
@@ -77,7 +84,8 @@
         p:transcoderRegistry-ref="shibboleth.AttributeRegistryService"
         p:activationCondition-ref="ScopeContainsOpenid">
         <property name="requestedClaimsLookupStrategy">
-            <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestedClaimsLookupFunction"/>
+            <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestedClaimsLookupFunction"
+                p:useOnlyRequestObjectPredicate-ref="#{'%{idp.oauth2.authorize.useOnlyRequestObject:DefaultUseOnlyRequestObjectCondition}'.trim()}"/>
         </property>
     </bean>
 
@@ -409,57 +417,61 @@
         <ref bean="AudienceClaimsValidator" />
     </util:list>
 
+    <bean id="DefaultRequestRedirectURILookupFunction"
+        class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestRedirectURILookupFunction"
+        p:useOnlyRequestObjectPredicate-ref="#{'%{idp.oauth2.authorize.useOnlyRequestObject:DefaultUseOnlyRequestObjectCondition}'.trim()}"/>
+
     <bean id="ValidateRedirectURI" class="net.shibboleth.idp.plugin.oidc.op.oauth2.profile.impl.ValidateRedirectURI"
         scope="prototype"
         p:requireRequestedValue="true"
-        p:unregisteredClientPolicyEnforcer="#{getObject('shibboleth.oidc.UnregisteredClientPolicyEnforcer') ?: getObject('shibboleth.oidc.DefaultUnregisteredClientPolicyEnforcer')}">
-        <property name="redirectURILookupStrategy">
-            <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestRedirectURILookupFunction"/>
-        </property>
-    </bean>
+        p:unregisteredClientPolicyEnforcer="#{getObject('shibboleth.oidc.UnregisteredClientPolicyEnforcer') ?: getObject('shibboleth.oidc.DefaultUnregisteredClientPolicyEnforcer')}"
+        p:redirectURILookupStrategy-ref="DefaultRequestRedirectURILookupFunction"/>
 
     <bean id="ValidateResponseType" class="net.shibboleth.idp.plugin.oidc.op.oauth2.profile.impl.ValidateResponseType"
         scope="prototype"
-        p:unregisteredClientPolicyEnforcer="#{getObject('shibboleth.oidc.UnregisteredClientPolicyEnforcer') ?: getObject('shibboleth.oidc.DefaultUnregisteredClientPolicyEnforcer')}">
-        <property name="requestedResponseTypeLookupStrategy">
-            <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestResponseTypeLookupFunction"/>
-        </property>
+        p:unregisteredClientPolicyEnforcer="#{getObject('shibboleth.oidc.UnregisteredClientPolicyEnforcer') ?: getObject('shibboleth.oidc.DefaultUnregisteredClientPolicyEnforcer')}"
+        p:requestedResponseTypeLookupStrategy-ref="RequestResponseTypeLookupFunction">
         <property name="validResponseTypesLookupStrategy">
-            <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultValidResponseTypesLookupFunction"/>            
+            <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultValidResponseTypesLookupFunction"
+                p:useOnlyRequestObjectPredicate-ref="#{'%{idp.oauth2.authorize.useOnlyRequestObject:DefaultUseOnlyRequestObjectCondition}'.trim()}"/>
         </property>
     </bean>
 
+    <bean id="DefaultRequestResponseModeLookupFunction"
+        class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestResponseModeLookupFunction"
+        p:useOnlyRequestObjectPredicate-ref="#{'%{idp.oauth2.authorize.useOnlyRequestObject:DefaultUseOnlyRequestObjectCondition}'.trim()}"/>
+
     <bean id="ValidateResponseMode" class="net.shibboleth.idp.plugin.oidc.op.oauth2.profile.impl.ValidateResponseMode"
-        scope="prototype">
-        <property name="requestedResponseModeLookupStrategy">
-            <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestResponseModeLookupFunction"/>
-        </property>
-    </bean>
+        scope="prototype"
+        p:requestedResponseModeLookupStrategy-ref="DefaultRequestResponseModeLookupFunction"/>
+
+    <bean id="DefaultRequestCodeChallengeLookupFunction"
+        class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestCodeChallengeLookupFunction"
+        p:useOnlyRequestObjectPredicate-ref="#{'%{idp.oauth2.authorize.useOnlyRequestObject:DefaultUseOnlyRequestObjectCondition}'.trim()}"/>
+
+    <bean id="DefaultRequestCodeChallengeMethodLookupFunction"
+        class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestCodeChallengeMethodLookupFunction"
+        p:useOnlyRequestObjectPredicate-ref="#{'%{idp.oauth2.authorize.useOnlyRequestObject:DefaultUseOnlyRequestObjectCondition}'.trim()}"/>
 
     <bean id="ValidateCodeChallenge" class="net.shibboleth.idp.plugin.oidc.op.oauth2.profile.impl.ValidateCodeChallenge"
-        scope="prototype">
-        <property name="codeChallengeLookupStrategy">
-            <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestCodeChallengeLookupFunction"/>
-        </property>
-        <property name="codeChallengeMethodLookupStrategy">
-            <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestCodeChallengeMethodLookupFunction"/>
-        </property>
-    </bean>
+        scope="prototype"
+        p:codeChallengeLookupStrategy-ref="DefaultRequestCodeChallengeLookupFunction"
+        p:codeChallengeMethodLookupStrategy-ref="DefaultRequestCodeChallengeMethodLookupFunction"/>
 
     <bean id="StoreDPoPProofKeyThumbprint" class="net.shibboleth.idp.plugin.oidc.op.oauth2.profile.impl.StoreDPoPProofKeyThumbprint"
         scope="prototype">
         <property name="dpopJktLookupStrategy">
-            <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestDPoPJktLookupFunction"/>
+            <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestDPoPJktLookupFunction"
+                p:useOnlyRequestObjectPredicate-ref="#{'%{idp.oauth2.authorize.useOnlyRequestObject:DefaultUseOnlyRequestObjectCondition}'.trim()}"/>
         </property>
     </bean>
 
     <bean id="ValidateScope" class="net.shibboleth.idp.plugin.oidc.op.oauth2.profile.impl.ValidateScope" scope="prototype"
-        p:allowedScopeLookupStrategy="#{getObject('shibboleth.oidc.AllowedScopeStrategy') ?: getObject('shibboleth.oidc.DefaultAllowedScopeStrategy')}">
+        p:allowedScopeLookupStrategy="#{getObject('shibboleth.oidc.AllowedScopeStrategy') ?: getObject('shibboleth.oidc.DefaultAllowedScopeStrategy')}"
+        p:requestedResponseTypeLookupStrategy-ref="RequestResponseTypeLookupFunction">
         <property name="requestedScopeLookupStrategy">
-            <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestedScopeLookupFunction"/>
-        </property>
-        <property name="requestedResponseTypeLookupStrategy">
-            <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestResponseTypeLookupFunction"/>
+            <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestedScopeLookupFunction"
+                p:useOnlyRequestObjectPredicate-ref="#{'%{idp.oauth2.authorize.useOnlyRequestObject:DefaultUseOnlyRequestObjectCondition}'.trim()}"/>
         </property>
     </bean>
 
@@ -469,7 +481,8 @@
         p:allowedAudienceLookupStrategy="#{getObject('shibboleth.oidc.AllowedAudienceStrategy') ?: getObject('shibboleth.oidc.DefaultAllowedAudienceStrategy')}" />
 
     <bean id="AuthenticationRequestAudienceLookupStrategy"
-        class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestAudienceLookupFunction" scope="prototype" />
+        class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestAudienceLookupFunction"
+        p:useOnlyRequestObjectPredicate-ref="#{'%{idp.oauth2.authorize.useOnlyRequestObject:DefaultUseOnlyRequestObjectCondition}'.trim()}"/>
 
     <bean id="PopulateClientStorageLoadContext"
         class="org.opensaml.storage.impl.client.PopulateClientStorageLoadContext" scope="prototype"
@@ -481,11 +494,8 @@
     <bean id="shibboleth.oidc.DefaultRevokeConsentPredicate"
         class="net.shibboleth.idp.plugin.oidc.op.profile.logic.DefaultRevokeConsentPredicate"
         p:revokeWithOfflineAccessScopePredicate="#{getObject('shibboleth.oidc.RevokeWithOfflineAccessScopePredicate') ?: getObject('shibboleth.Conditions.TRUE')}"
-        p:revokeWithConsentPromptPredicate="#{getObject('shibboleth.oidc.RevokeWithConsentPromptPredicate') ?: getObject('shibboleth.Conditions.TRUE')}">
-        <property name="promptLookupStrategy">
-            <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestedPromptLookupFunction"/>
-        </property>
-    </bean>
+        p:revokeWithConsentPromptPredicate="#{getObject('shibboleth.oidc.RevokeWithConsentPromptPredicate') ?: getObject('shibboleth.Conditions.TRUE')}"
+        p:promptLookupStrategy-ref="DefaultRequestedPromptLookupFunction"/>
 
     <bean id="SetAuthenticationTimeToResponseContext"
         class="net.shibboleth.idp.plugin.oidc.op.profile.impl.SetAuthenticationTimeToResponseContext" scope="prototype" />
@@ -668,23 +678,21 @@
     <bean id="SetConsentToResponseContext"
         class="net.shibboleth.idp.plugin.oidc.op.profile.impl.SetConsentToResponseContext" scope="prototype" />
 
+    <bean id="DefaultRequestNonceLookupFunction"
+        class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestNonceLookupFunction"
+        p:useOnlyRequestObjectPredicate-ref="#{'%{idp.oauth2.authorize.useOnlyRequestObject:DefaultUseOnlyRequestObjectCondition}'.trim()}"/>
+
     <bean id="SetAuthorizationCodeToResponseContext"
         class="net.shibboleth.idp.plugin.oidc.op.oauth2.profile.impl.SetAuthorizationCodeToResponseContext" scope="prototype"
         p:dataSealer-ref="#{'%{idp.oidc.tokenSealer:shibboleth.oidc.TokenSealer}'.trim()}"
         p:xmlSafeIdentifier="%{idp.oidc.xmlSafeIdentifiers:true}"
-        p:identifierGeneratorLookupStrategy-ref="shibboleth.oidc.DefaultIdentifierGenerationStrategy">
+        p:identifierGeneratorLookupStrategy-ref="shibboleth.oidc.DefaultIdentifierGenerationStrategy"
+        p:codeChallengeLookupStrategy-ref="DefaultRequestCodeChallengeLookupFunction"
+        p:codeChallengeMethodLookupStrategy-ref="DefaultRequestCodeChallengeMethodLookupFunction"
+        p:requestNonceLookupStrategy-ref="DefaultRequestNonceLookupFunction">
         <property name="activationCondition">
             <ref bean="AuthorizeCodeRequested" />
         </property>
-        <property name="codeChallengeLookupStrategy">
-            <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestCodeChallengeLookupFunction"/>
-        </property>
-        <property name="codeChallengeMethodLookupStrategy">
-            <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestCodeChallengeMethodLookupFunction"/>
-        </property>
-        <property name="requestNonceLookupStrategy">
-            <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestNonceLookupFunction"/>
-        </property>
     </bean>
 
     <!-- If access token is strictly for UserInfo endpoint... -->
@@ -975,11 +983,8 @@
         scope="prototype" />
 
     <bean id="AddNonceToIDToken" class="net.shibboleth.idp.plugin.oidc.op.profile.impl.AddNonceToIDToken"
-        scope="prototype">
-        <property name="requestNonceLookupStrategy">
-            <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestNonceLookupFunction"/>
-        </property>
-    </bean>
+        scope="prototype"
+        p:requestNonceLookupStrategy-ref="DefaultRequestNonceLookupFunction"/>
 
     <bean id="AddAccessTokenHashToIDToken"
             class="net.shibboleth.idp.plugin.oidc.op.profile.impl.AddAccessTokenHashToIDToken" scope="prototype"
@@ -1062,15 +1067,14 @@
         class="net.shibboleth.idp.plugin.oidc.op.session.impl.OIDCRPSessionCreationStrategy"
         c:lifetime="%{idp.session.defaultSPlifetime:PT2H}"/>
 
+    <bean id="DefaultRequestStateLookupFunction"
+        class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestStateLookupFunction"
+        p:useOnlyRequestObjectPredicate-ref="#{'%{idp.oauth2.authorize.useOnlyRequestObject:DefaultUseOnlyRequestObjectCondition}'.trim()}"/>
+
     <bean id="FormOutboundMessage"
-        class="net.shibboleth.idp.plugin.oidc.op.profile.impl.FormOutboundAuthenticationResponseMessage" scope="prototype">
-        <property name="requestedResponseModeLookupStrategy">
-            <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestResponseModeLookupFunction"/>
-        </property>
-        <property name="requestedStateLookupStrategy">
-            <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestStateLookupFunction"/>
-        </property>
-    </bean>
+        class="net.shibboleth.idp.plugin.oidc.op.profile.impl.FormOutboundAuthenticationResponseMessage" scope="prototype"
+        p:requestedResponseModeLookupStrategy-ref="DefaultRequestResponseModeLookupFunction"
+        p:requestedStateLookupStrategy-ref="DefaultRequestStateLookupFunction"/>
 
     <bean id="PopulateClientStorageSaveContext"
         class="org.opensaml.storage.impl.client.PopulateClientStorageSaveContext" scope="prototype"
@@ -1080,32 +1084,24 @@
         class="net.shibboleth.idp.plugin.oidc.op.oauth2.profile.impl.ValidateRedirectURI"
         scope="prototype"
         p:requireRequestedValue="true"
-        p:unregisteredClientPolicyEnforcer="#{getObject('shibboleth.oidc.UnregisteredClientPolicyEnforcer') ?: getObject('shibboleth.oidc.DefaultUnregisteredClientPolicyEnforcer')}">
+        p:unregisteredClientPolicyEnforcer="#{getObject('shibboleth.oidc.UnregisteredClientPolicyEnforcer') ?: getObject('shibboleth.oidc.DefaultUnregisteredClientPolicyEnforcer')}"
+        p:redirectURILookupStrategy-ref="DefaultRequestRedirectURILookupFunction">
         <property name="activationCondition">
             <bean parent="shibboleth.Conditions.Expression"
                 c:expression="#input.ensureOutboundMessageContext().ensureSubcontext(T(net.shibboleth.idp.plugin.oidc.op.messaging.context.OIDCAuthenticationResponseContext)).isRequestObjectFailure()" />
         </property>
-        <property name="redirectURILookupStrategy">
-            <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestRedirectURILookupFunction"/>
-        </property>
     </bean>
 
     <bean id="BuildErrorResponseFromEvent"
         class="net.shibboleth.idp.plugin.oidc.op.profile.impl.BuildAuthenticationErrorResponseFromEvent" scope="prototype"
         p:httpServletResponseSupplier-ref="shibboleth.HttpServletResponseSupplier"
-        p:mappedErrors="#{getObject('shibboleth.oidc.authorize.MappedErrors') ?: getObject('shibboleth.oidc.authorize.DefaultMappedErrors')}">
+        p:mappedErrors="#{getObject('shibboleth.oidc.authorize.MappedErrors') ?: getObject('shibboleth.oidc.authorize.DefaultMappedErrors')}"
+        p:requestedResponseTypeLookupStrategy-ref="RequestResponseTypeLookupFunction"
+        p:requestedResponseModeLookupStrategy-ref="DefaultRequestResponseModeLookupFunction"
+        p:requestedStateLookupStrategy-ref="DefaultRequestStateLookupFunction">
         <property name="eventContextLookupStrategy">
             <bean class="net.shibboleth.idp.profile.context.navigate.WebFlowCurrentEventLookupFunction" />
         </property>
-        <property name="requestedResponseModeLookupStrategy">
-            <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestResponseModeLookupFunction"/>
-        </property>
-        <property name="requestedStateLookupStrategy">
-            <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestStateLookupFunction"/>
-        </property>
-        <property name="requestedResponseTypeLookupStrategy">
-            <bean class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestResponseTypeLookupFunction"/>
-        </property>
     </bean>
 
     <bean id="ErrorViewPopulateAuditContext" parent="shibboleth.AbstractPopulateAuditContext"
@@ -1114,8 +1110,9 @@
     <bean id="MapEventToView" class="net.shibboleth.idp.profile.context.navigate.SpringEventToViewLookupFunction"
         p:defaultView-ref="shibboleth.DefaultErrorView" p:eventMap="#{getObject('shibboleth.EventViewMap')}" />
 
-    <bean id="RequestResponseTypeLookupFunction" scope="prototype"
-        class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestResponseTypeLookupFunction"/>
+    <bean id="RequestResponseTypeLookupFunction"
+        class="net.shibboleth.idp.plugin.oidc.op.messaging.context.navigate.DefaultRequestResponseTypeLookupFunction"
+        p:useOnlyRequestObjectPredicate-ref="#{'%{idp.oauth2.authorize.useOnlyRequestObject:DefaultUseOnlyRequestObjectCondition}'.trim()}"/>
 
     <bean id="IDTokenRequested" parent="shibboleth.Conditions.Expression" p:customObject-ref="RequestResponseTypeLookupFunction">
         <constructor-arg>
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 d738f0d8..f46445dc 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
@@ -237,7 +237,9 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
         setRequestParameters(List.of(new Pair<>("client_id", clientId),
                 new Pair<>("response_type", "code"),
                 new Pair<>("scope", "openid profile"),
-                new Pair<>("request_uri", createParGeneratedRequestUri(clientId).toString()),
+                new Pair<>("request_uri", createParGeneratedRequestUri(Map.of(
+                        "client_id", clientId, "redirect_uri", redirectUri,
+                        "response_type", "code", "scope", "openid profile")).toString()),
                 new Pair<>("redirect_uri", redirectUri)));
         request.setMethod("GET");
         final OIDCClientMetadata metadata = buildMetadataSkeleton();
@@ -304,7 +306,7 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
         assertErrorCode(result, "invalid_request");
     }
 
-    protected URI createParGeneratedRequestUri(final String clientId) {
+    protected URI createParGeneratedRequestUri(final Map<String, Object> parameters) {
         final DefaultPushedAuthorizationRequestUriSerializationFunction parGenerator =
                 new DefaultPushedAuthorizationRequestUriSerializationFunction();
         parGenerator.setObjectMapper(new ObjectMapper());
@@ -316,7 +318,7 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
         } catch (ComponentInitializationException e) {
             Assert.fail("Could not initialize PAR generator", e);
         }
-        return parGenerator.apply(null, Map.of("client_id", clientId, "redirect_uri", redirectUri));
+        return parGenerator.apply(null, parameters);
     }
     
     @Test
@@ -325,7 +327,9 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
         setRequestParameters(List.of(new Pair<>("client_id", clientId),
                 new Pair<>("response_type", "code"),
                 new Pair<>("scope", "openid profile"),
-                new Pair<>("request_uri", createParGeneratedRequestUri(clientId).toString()),
+                new Pair<>("request_uri", createParGeneratedRequestUri(Map.of(
+                        "client_id", clientId, "redirect_uri", redirectUri,
+                        "response_type", "code", "scope", "openid profile")).toString()),
                 new Pair<>("redirect_uri", redirectUri)));
         request.setMethod("GET");
         final OIDCClientMetadata metadata = buildMetadataSkeleton();
@@ -347,6 +351,37 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
         Assert.assertNull(successResponse.getIssuer());
     }
 
+    @Test
+    public void testWithAuthorizationCodeFlow_parRespectedForScope() throws IOException, SessionException,
+            URISyntaxException {
+        setRequestParameters(List.of(new Pair<>("client_id", clientId),
+                new Pair<>("response_type", "code"),
+                new Pair<>("scope", "openid profile"),
+                new Pair<>("request_uri", createParGeneratedRequestUri(Map.of(
+                        "client_id", clientId, "redirect_uri", redirectUri,
+                        "response_type", "code", "scope", "profile")).toString()),
+                new Pair<>("redirect_uri", redirectUri)));
+        request.setMethod("GET");
+        final OIDCClientMetadata metadata = buildMetadataSkeleton();
+        metadata.setRedirectionURIs(Set.of(new URI(redirectUri)));
+        metadata.setScope(scope);
+        metadata.setCustomField("audience", List.of("https://resource.example.org"));
+        storeMetadataObject(storageService, clientId, clientSecret, metadata);
+
+        initializeThreadLocals();
+        
+        final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+        final AuthenticationResponse responseMessage = parseSuccessResponse(result, AuthenticationResponse.class);
+        final AuthenticationSuccessResponse successResponse = responseMessage.toSuccessResponse();
+        Assert.assertEquals(successResponse.getRedirectionURI().toString(), redirectUri);
+        Assert.assertNull(successResponse.getIDToken());
+        Assert.assertNull(successResponse.getAccessToken());
+        Assert.assertNotNull(successResponse.getAuthorizationCode());
+        Assert.assertNotNull(getSidFromAuthorizeCodeClaimsSet(successResponse));
+        Assert.assertEquals(getScopeFromAuthorizeCodeClaimsSet(successResponse), Scope.parse("profile"));
+        Assert.assertNull(successResponse.getIssuer());
+    }
+
     @Test
     public void testWithAuthorizationCodeFlow_defaultResponseModeNotAllowed() throws IOException, SessionException {
         setRequestParameters(List.of(new Pair<>("client_id", clientIdFragmentResponseMode),
@@ -2355,6 +2390,18 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
         }
     }
 
+    protected Scope getScopeFromAuthorizeCodeClaimsSet(final AuthorizationSuccessResponse successResponse) {
+        Assert.assertNotNull(successResponse.getAuthorizationCode());
+        final AuthorizeCodeClaimsSet claims;
+        try {
+            claims = AuthorizeCodeClaimsSet.parse(successResponse.getAuthorizationCode().getValue(), getDataSealer());
+            Assert.assertNotNull(claims.getScope());
+            return claims.getScope();
+        } catch (ParseException | DataSealerException e) {
+            return null;
+        }
+    }
+
     protected List<String> getAudienceFromAuthorizeCodeClaimsSet(final AuthenticationSuccessResponse successResponse) {
         Assert.assertNotNull(successResponse.getAuthorizationCode());
         final AuthorizeCodeClaimsSet claims;

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


More information about the commits mailing list