[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