[java-oidc-common] 02/02: JCOMOIDC-108 - Profile Configuration for OAuth2 PAR

Henri Mikkonen henri.mikkonen at iki.fi
Wed Apr 24 07:32:20 UTC 2024


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

hjmikkon pushed a commit to branch main
in repository java-oidc-common.

View the commit online:
http://git.shibboleth.net/view/?p=java-oidc-common.git;a=commit;h=1ffd787d535113798c8e108d66a12ae25812e2b4

commit 1ffd787d535113798c8e108d66a12ae25812e2b4
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Wed Apr 24 10:31:23 2024 +0300

    JCOMOIDC-108 - Profile Configuration for OAuth2 PAR
    
    https://shibboleth.atlassian.net/browse/JCOMOIDC-108
    
    Initial (incomplete) version of the profile configuration interface
    and its default implementation + lookup functions. WIP.
---
 ...laimsSetManipulationStrategyLookupFunction.java |  57 ++++++
 ...horizationRequestUriLifetimeLookupFunction.java |  52 ++++++
 ...dAuthorizationRequestUriTypeLookupFunction.java |  50 ++++++
 ...th2PushedAuthorizationRequestConfiguration.java |  79 +++++++++
 ...th2PushedAuthorizationRequestConfiguration.java | 195 +++++++++++++++++++++
 5 files changed, 433 insertions(+)

diff --git a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/navigate/PushedAuthorizationRequestUriClaimsSetManipulationStrategyLookupFunction.java b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/navigate/PushedAuthorizationRequestUriClaimsSetManipulationStrategyLookupFunction.java
new file mode 100644
index 0000000..6f687e1
--- /dev/null
+++ b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/navigate/PushedAuthorizationRequestUriClaimsSetManipulationStrategyLookupFunction.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.oidc.profile.config.navigate;
+
+import java.util.Map;
+import java.util.function.BiFunction;
+
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.oidc.profile.oauth2.config.OAuth2PushedAuthorizationRequestConfiguration;
+import net.shibboleth.profile.config.ProfileConfiguration;
+import net.shibboleth.profile.context.RelyingPartyContext;
+import net.shibboleth.profile.context.navigate.AbstractRelyingPartyLookupFunction;
+
+/**
+ * A function that returns {@link
+ * OAuth2PushedAuthorizationRequestConfiguration#getRequestUriClaimsSetManipulationStrategy(ProfileRequestContext)}
+ * if such a profile is available from a {@link RelyingPartyContext} obtained via a lookup function,
+ * by default a child of the {@link ProfileRequestContext}.
+ * 
+ * <p>If a specific setting is unavailable, a null value is returned.</p>
+ * 
+ * @since 3.2.0
+ */
+public class PushedAuthorizationRequestUriClaimsSetManipulationStrategyLookupFunction  extends
+    AbstractRelyingPartyLookupFunction<BiFunction<ProfileRequestContext,Map<String,Object>,Map<String,Object>>> {
+
+    /** {@inheritDoc} */
+    @Override
+    @Nullable public BiFunction<ProfileRequestContext,Map<String,Object>,Map<String,Object>> apply(
+            @Nullable final ProfileRequestContext input) {
+        final RelyingPartyContext rpc = getRelyingPartyContextLookupStrategy().apply(input);
+        if (rpc != null) {
+            final ProfileConfiguration pc = rpc.getProfileConfig();
+            if (pc instanceof OAuth2PushedAuthorizationRequestConfiguration parConfig) {
+                return parConfig.getRequestUriClaimsSetManipulationStrategy(input);
+            }
+        }
+        
+        return null;
+    }
+
+}
\ No newline at end of file
diff --git a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/navigate/PushedAuthorizationRequestUriLifetimeLookupFunction.java b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/navigate/PushedAuthorizationRequestUriLifetimeLookupFunction.java
new file mode 100644
index 0000000..1c7204e
--- /dev/null
+++ b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/navigate/PushedAuthorizationRequestUriLifetimeLookupFunction.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.oidc.profile.config.navigate;
+
+import java.time.Duration;
+
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.profile.config.ProfileConfiguration;
+import net.shibboleth.profile.context.RelyingPartyContext;
+import net.shibboleth.profile.context.navigate.AbstractRelyingPartyLookupFunction;
+import net.shibboleth.oidc.profile.oauth2.config.OAuth2PushedAuthorizationRequestConfiguration;
+
+/**
+ * A function that returns
+ * {@link OAuth2PushedAuthorizationRequestConfiguration#getRequestUriLifetime(ProfileRequestContext)}
+ * if such a profile is available from a {@link RelyingPartyContext} obtained via a lookup function,
+ * by default a child of the {@link ProfileRequestContext}.
+ * 
+ * <p>If a specific setting is unavailable, a null value is returned.</p>
+ */
+public class PushedAuthorizationRequestUriLifetimeLookupFunction extends AbstractRelyingPartyLookupFunction<Duration> {
+
+    /** {@inheritDoc} */
+    @Override
+    @Nullable public Duration apply(@Nullable final ProfileRequestContext input) {
+        final RelyingPartyContext rpc = getRelyingPartyContextLookupStrategy().apply(input);
+        if (rpc != null) {
+            final ProfileConfiguration pc = rpc.getProfileConfig();
+            if (pc instanceof OAuth2PushedAuthorizationRequestConfiguration parConfig) {
+                return parConfig.getRequestUriLifetime(input);
+            }
+        }
+        
+        return null;
+    }
+
+}
\ No newline at end of file
diff --git a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/navigate/PushedAuthorizationRequestUriTypeLookupFunction.java b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/navigate/PushedAuthorizationRequestUriTypeLookupFunction.java
new file mode 100644
index 0000000..c3940f7
--- /dev/null
+++ b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/navigate/PushedAuthorizationRequestUriTypeLookupFunction.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.oidc.profile.config.navigate;
+
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.profile.config.ProfileConfiguration;
+import net.shibboleth.profile.context.RelyingPartyContext;
+import net.shibboleth.profile.context.navigate.AbstractRelyingPartyLookupFunction;
+import net.shibboleth.oidc.profile.oauth2.config.OAuth2PushedAuthorizationRequestConfiguration;
+
+/**
+ * A function that returns
+ * {@link OAuth2PushedAuthorizationRequestConfiguration#getRequestUriType(ProfileRequestContext)}
+ * if such a profile is available from a {@link RelyingPartyContext} obtained via a lookup function,
+ * by default a child of the {@link ProfileRequestContext}.
+ * 
+ * <p>If a specific setting is unavailable, a null value is returned.</p>
+ */
+public class PushedAuthorizationRequestUriTypeLookupFunction extends AbstractRelyingPartyLookupFunction<String> {
+
+    /** {@inheritDoc} */
+    @Override
+    @Nullable public String apply(@Nullable final ProfileRequestContext input) {
+        final RelyingPartyContext rpc = getRelyingPartyContextLookupStrategy().apply(input);
+        if (rpc != null) {
+            final ProfileConfiguration pc = rpc.getProfileConfig();
+            if (pc instanceof OAuth2PushedAuthorizationRequestConfiguration parConfig) {
+                return parConfig.getRequestUriType(input);
+            }
+        }
+        
+        return null;
+    }
+
+}
\ No newline at end of file
diff --git a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/oauth2/config/OAuth2PushedAuthorizationRequestConfiguration.java b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/oauth2/config/OAuth2PushedAuthorizationRequestConfiguration.java
new file mode 100644
index 0000000..5d89514
--- /dev/null
+++ b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/oauth2/config/OAuth2PushedAuthorizationRequestConfiguration.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.oidc.profile.oauth2.config;
+
+import java.time.Duration;
+import java.util.Map;
+import java.util.function.BiFunction;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.profile.config.OverriddenIssuerProfileConfiguration;
+import net.shibboleth.shared.annotation.ConfigurationSetting;
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.annotation.constraint.Positive;
+
+/**
+ * Profile configuration for OAuth2 Pushed Authorization Requests (PAR).
+ * 
+ * @since 3.2.0
+ */
+public interface OAuth2PushedAuthorizationRequestConfiguration extends OAuth2ClientAuthenticableProfileConfiguration, 
+    OAuth2ProfileConfiguration, OverriddenIssuerProfileConfiguration {    
+
+    /** OAuth2 Token Revocation URI. */
+    @Nonnull @NotEmpty public static final String PROTOCOL_URI = "https://tools.ietf.org/html/rfc9126";
+
+    /** ID for this profile configuration. */
+    @Nonnull @NotEmpty public static final String PROFILE_ID = "http://shibboleth.net/ns/profiles/oauth2/par";
+
+    /**
+     * Get request URI type.
+     * 
+     * @param profileRequestContext profile request context
+     * 
+     * @return request URI type, or null for unspecified/opaque
+     */
+    @ConfigurationSetting(name="requestUriType")
+    @Nullable @NotEmpty String getRequestUriType(@Nullable final ProfileRequestContext profileRequestContext);
+     
+    /**
+     * Get request URI lifetime.
+     * 
+     * <p>Defaults to 1 minute.</p>
+     * 
+     * @param profileRequestContext profile request context
+     * 
+     * @return request URI lifetime
+     */
+    @ConfigurationSetting(name="requestUriLifetime")
+    @Positive @Nonnull Duration getRequestUriLifetime(@Nullable final ProfileRequestContext profileRequestContext);
+
+    /**
+     * Get the bi-function for manipulating request URI claims set.
+     * 
+     * @param profileRequestContext profile request context
+     * 
+     * @return the bi-function for manipulating request URI claims set
+     */
+    @ConfigurationSetting(name="requestUriClaimsSetManipulationStrategy")
+    @Nullable BiFunction<ProfileRequestContext,Map<String,Object>,Map<String,Object>>
+        getRequestUriClaimsSetManipulationStrategy(
+                @Nullable final ProfileRequestContext profileRequestContext);
+
+}
diff --git a/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/oauth2/config/impl/DefaultOAuth2PushedAuthorizationRequestConfiguration.java b/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/oauth2/config/impl/DefaultOAuth2PushedAuthorizationRequestConfiguration.java
new file mode 100644
index 0000000..69f71fb
--- /dev/null
+++ b/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/oauth2/config/impl/DefaultOAuth2PushedAuthorizationRequestConfiguration.java
@@ -0,0 +1,195 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.oidc.profile.oauth2.config.impl;
+
+
+import java.time.Duration;
+import java.util.Map;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.oidc.profile.oauth2.config.OAuth2PushedAuthorizationRequestConfiguration;
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.annotation.constraint.Positive;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.logic.FunctionSupport;
+import net.shibboleth.shared.primitive.StringSupport;
+
+/**
+ *  Implementation of a profile configuration for the OAuth2 Pushed Authorization Requests (PAR).
+ *  
+ *  @since 3.2.0
+ */
+public class DefaultOAuth2PushedAuthorizationRequestConfiguration
+    extends AbstractOAuth2ClientAuthenticableProfileConfiguration
+    implements OAuth2PushedAuthorizationRequestConfiguration {
+
+    /** OAuth2 pushed authorization request profile counter name. */
+    @Nonnull @NotEmpty public static final String PROFILE_COUNTER = "net.shibboleth.idp.profiles.oauth2.par";
+
+    /** Lookup function to override issuer value. */
+    @Nonnull private Function<ProfileRequestContext,String> issuerLookupStrategy;
+
+    /** Lookup function to supply request URI type. */
+    @Nonnull private Function<ProfileRequestContext,String> requestUriTypeLookupStrategy;
+
+    /** Lookup function to supply request URI lifetime. */
+    @Nonnull private Function<ProfileRequestContext,Duration> requestUriLifetimeLookupStrategy;
+
+    /** Lookup function to supply strategy bi-function for manipulating request URI claims set. */ 
+    @Nonnull
+    private Function<ProfileRequestContext,BiFunction<ProfileRequestContext,Map<String,Object>,Map<String,Object>>>
+        requestUriClaimsSetManipulationStrategyLookupStrategy;    
+
+    /**
+     * Constructor.
+     */
+    public DefaultOAuth2PushedAuthorizationRequestConfiguration() {
+        this(PROFILE_ID);
+    }
+
+    /**
+     * Creates a new configuration instance.
+     *
+     * @param profileId Unique profile identifier.
+     */
+    public DefaultOAuth2PushedAuthorizationRequestConfiguration(@Nonnull @NotEmpty final String profileId) {
+        super(profileId);
+        issuerLookupStrategy = FunctionSupport.constant(null);
+        requestUriTypeLookupStrategy = FunctionSupport.constant(null);
+        requestUriLifetimeLookupStrategy = FunctionSupport.constant(Duration.ofMinutes(1));
+        requestUriClaimsSetManipulationStrategyLookupStrategy = FunctionSupport.constant(null);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    @Nullable @NotEmpty public String getIssuer(@Nullable final ProfileRequestContext profileRequestContext) {
+        return issuerLookupStrategy.apply(profileRequestContext);
+    }
+    
+    /**
+     * Set overridden issuer value.
+     * 
+     * @param issuer issuer value
+     */
+    public void setIssuer(@Nullable @NotEmpty final String issuer) {
+        issuerLookupStrategy = FunctionSupport.constant(issuer);
+    }
+    
+    /**
+     * Sets lookup strategy for overridden issuer value.
+     * 
+     * @param strategy lookup strategy
+     */
+    public void setIssuerLookupStrategy(@Nonnull final Function<ProfileRequestContext,String> strategy) {
+        issuerLookupStrategy = Constraint.isNotNull(strategy, "Issuer lookup strategy cannot be null");
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    @Nullable @NotEmpty public String getRequestUriType(@Nullable final ProfileRequestContext profileRequestContext) {
+         return requestUriTypeLookupStrategy.apply(profileRequestContext);
+     }
+
+    /**
+     * Set request URI type.
+     * 
+     * @param type token type, or null for unspecified/opaque
+     */
+     public void setRequestUriType(@Nullable @NotEmpty final String type) {
+         requestUriTypeLookupStrategy = FunctionSupport.constant(StringSupport.trimOrNull(type));
+     }
+    
+    /**
+     * Set lookup strategy for request URI type.
+     * 
+     * @param strategy lookup strategy
+     */
+     public void setRequestUriTypeLookupStrategy(@Nonnull final Function<ProfileRequestContext,String> strategy) {
+         requestUriTypeLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
+     }
+
+     /** {@inheritDoc} */
+    @Override
+    @Positive @Nonnull
+    public Duration getRequestUriLifetime(@Nullable final ProfileRequestContext profileRequestContext) {
+        final Duration lifetime = requestUriLifetimeLookupStrategy.apply(profileRequestContext);
+        
+        Constraint.isTrue(lifetime != null && !lifetime.isZero() && !lifetime.isNegative(),
+                "Request URI lifetime must be greater than 0");
+        assert lifetime != null;
+        return lifetime;
+    }
+    
+    /**
+     * Set the lifetime of an request URI.
+     * 
+     * @param lifetime lifetime of an request URI in milliseconds
+     */
+    public void setRequestUriLifetime(@Positive @Nonnull final Duration lifetime) {
+        final Duration tokenLifetime = Constraint.isNotNull(lifetime, "request URI lifetime cannot be null");
+        Constraint.isTrue(!tokenLifetime.isZero() && !tokenLifetime.isNegative(),
+                "request URI lifetime must be greater than 0");
+        
+        requestUriLifetimeLookupStrategy = FunctionSupport.constant(tokenLifetime);
+    }
+    
+    /**
+     * Set a lookup strategy for the request URI lifetime.
+     *
+     * @param strategy lookup strategy
+     */
+    public void setRequestUriLifetimeLookupStrategy(
+            @Nullable final Function<ProfileRequestContext,Duration> strategy) {
+        requestUriLifetimeLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    @Nullable
+    public BiFunction<ProfileRequestContext,Map<String,Object>,Map<String,Object>>
+        getRequestUriClaimsSetManipulationStrategy(
+            @Nullable final ProfileRequestContext profileRequestContext) {
+        return requestUriClaimsSetManipulationStrategyLookupStrategy.apply(profileRequestContext);
+    }
+
+    /**
+     * Set the bi-function for manipulating request URI claims set.
+     * 
+     * @param strategy bi-function for manipulating request URI claims set
+     */
+    public void setRequestUriClaimsSetManipulationStrategy(
+            @Nullable final BiFunction<ProfileRequestContext,Map<String,Object>,Map<String,Object>> strategy) {
+        requestUriClaimsSetManipulationStrategyLookupStrategy = FunctionSupport.constant(strategy);
+    }
+
+    /**
+     * Set a lookup strategy for the bi-function for manipulating request URI claims set.
+     *
+     * @param strategy lookup strategy
+     */
+    public void setRequestUriClaimsSetManipulationStrategyLookupStrategy(@Nonnull final 
+            Function<ProfileRequestContext,BiFunction<ProfileRequestContext,Map<String,Object>,Map<String,Object>>>
+            strategy) {
+        requestUriClaimsSetManipulationStrategyLookupStrategy = Constraint.isNotNull(strategy,
+                "Lookup strategy cannot be null");
+    }
+
+}
\ No newline at end of file

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


More information about the commits mailing list