[java-oidc-common] 03/04: JCOMOIDC-87 - Profile configuration for OIDC logout
Henri Mikkonen
henri.mikkonen at iki.fi
Wed Jan 3 10:57:26 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=f10cd9b97f1323a1dfae3779922f5a06f6c0cf0b
commit f10cd9b97f1323a1dfae3779922f5a06f6c0cf0b
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Mon Oct 16 18:23:07 2023 +0300
JCOMOIDC-87 - Profile configuration for OIDC logout
https://shibboleth.atlassian.net/browse/JCOMOIDC-87
New properties to OIDC.Logout to server RP-initiated logout
- requireIdTokenHint
- logoutHintMatchingStrategy
---
.../config/OIDCLogoutProfileConfiguration.java | 25 +++++++++
.../config/logic/RequireIdTokenHintPredicate.java | 47 ++++++++++++++++
.../LogoutHintMatchingStrategyLookupFunction.java | 54 ++++++++++++++++++
.../shibboleth/oidc/profile/core/OidcEventIds.java | 13 ++++-
oidc-common-profile-impl/pom.xml | 5 ++
.../impl/DefaultOIDCLogoutConfiguration.java | 64 ++++++++++++++++++++++
6 files changed, 207 insertions(+), 1 deletion(-)
diff --git a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/OIDCLogoutProfileConfiguration.java b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/OIDCLogoutProfileConfiguration.java
index ff77c79..02be179 100644
--- a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/OIDCLogoutProfileConfiguration.java
+++ b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/OIDCLogoutProfileConfiguration.java
@@ -14,11 +14,14 @@
package net.shibboleth.oidc.profile.config;
+import java.util.function.BiPredicate;
+
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.opensaml.profile.context.ProfileRequestContext;
+import net.shibboleth.idp.session.SPSession;
import net.shibboleth.oidc.profile.oauth2.config.OAuth2TokenEncryptionProfileConfiguration;
import net.shibboleth.shared.annotation.ConfigurationSetting;
import net.shibboleth.shared.annotation.constraint.NotEmpty;
@@ -63,4 +66,26 @@ public interface OIDCLogoutProfileConfiguration extends OAuth2TokenEncryptionPro
*/
@ConfigurationSetting(name="revokeTokens")
boolean isRevokeTokens(@Nullable final ProfileRequestContext profileRequestContext);
+
+ /**
+ * Get whether to require the use of id_token_hint in an OIDC RP-initiated logout sequence.
+ *
+ * @param profileRequestContext profile request context
+ *
+ * @return true iff the use of id_token_hint is required
+ */
+ @ConfigurationSetting(name="requireIdTokenHint")
+ boolean isRequireIdTokenHint(@Nullable final ProfileRequestContext profileRequestContext);
+
+ /**
+ * Get the bi-predicate for matching logout hint to an existing session in an OIDC RP-initiated logout sequence.
+ *
+ * @param profileRequestContext profile request context
+ *
+ * @return the bi-predicate for matching logout hint to an existing session.
+ */
+ @ConfigurationSetting(name="logoutHintMatchingStrategy")
+ @Nonnull BiPredicate<String,SPSession> getLogoutHintMatchingStrategy(
+ @Nullable final ProfileRequestContext profileRequestContext);
+
}
\ No newline at end of file
diff --git a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/logic/RequireIdTokenHintPredicate.java b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/logic/RequireIdTokenHintPredicate.java
new file mode 100644
index 0000000..475e4aa
--- /dev/null
+++ b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/logic/RequireIdTokenHintPredicate.java
@@ -0,0 +1,47 @@
+/*
+ * 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.logic;
+
+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.logic.AbstractRelyingPartyPredicate;
+import net.shibboleth.oidc.profile.config.OIDCLogoutProfileConfiguration;
+
+/**
+ * A predicate implementation that forwards to
+ * {@link OIDCLogoutProfileConfiguration#isRequireIdTokenHint(ProfileRequestContext)}.
+ *
+ * @since 3.1.0
+ */
+public class RequireIdTokenHintPredicate extends AbstractRelyingPartyPredicate {
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean test(@Nullable final ProfileRequestContext input) {
+ final RelyingPartyContext rpc = getRelyingPartyContextLookupStrategy().apply(input);
+ if (rpc != null) {
+ final ProfileConfiguration pc = rpc.getProfileConfig();
+ if (pc instanceof OIDCLogoutProfileConfiguration olpc) {
+ return olpc.isRequireIdTokenHint(input);
+ }
+ }
+ return false;
+ }
+
+}
\ No newline at end of file
diff --git a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/navigate/LogoutHintMatchingStrategyLookupFunction.java b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/navigate/LogoutHintMatchingStrategyLookupFunction.java
new file mode 100644
index 0000000..1ce9671
--- /dev/null
+++ b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/navigate/LogoutHintMatchingStrategyLookupFunction.java
@@ -0,0 +1,54 @@
+/*
+ * 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.function.BiPredicate;
+
+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.idp.session.SPSession;
+import net.shibboleth.oidc.profile.config.OIDCLogoutProfileConfiguration;
+
+/**
+ * A function that returns {@link OIDCLogoutProfileConfiguration#getLogoutHintMatchingStrategy(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.1.0
+ */
+public class LogoutHintMatchingStrategyLookupFunction extends
+ AbstractRelyingPartyLookupFunction<BiPredicate<String,SPSession>> {
+
+ /** {@inheritDoc} */
+ @Override @Nullable public BiPredicate<String,SPSession> apply(@Nullable final ProfileRequestContext input) {
+ final RelyingPartyContext rpc = getRelyingPartyContextLookupStrategy().apply(input);
+ if (rpc != null) {
+ final ProfileConfiguration pc = rpc.getProfileConfig();
+ if (pc instanceof OIDCLogoutProfileConfiguration olpc) {
+ return olpc.getLogoutHintMatchingStrategy(input);
+ }
+ }
+
+ return null;
+ }
+
+}
\ No newline at end of file
diff --git a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/core/OidcEventIds.java b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/core/OidcEventIds.java
index c990d02..6b8821d 100644
--- a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/core/OidcEventIds.java
+++ b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/core/OidcEventIds.java
@@ -78,7 +78,12 @@ public final class OidcEventIds {
* The request object or uri is missing in request, even though it's mandatory.
*/
@Nonnull @NotEmpty public static final String MISSING_MANDATORY_REQUEST_OBJECT = "MissingMandatoryRequestObject";
-
+
+ /**
+ * The id_token hint is missing in request, even though it's mandatory.
+ */
+ @Nonnull @NotEmpty public static final String MISSING_MANDATORY_ID_TOKEN_HINT = "MissingMandatoryIdTokenHint";
+
/**
* The revocation attempt failed.
*/
@@ -125,6 +130,12 @@ public final class OidcEventIds {
*/
@Nonnull @NotEmpty public static final String INVALID_SCOPE = "InvalidScope";
+
+ /**
+ * ID of event returned upon an inability to locate any matching session for a LogoutRequest.
+ */
+ @Nonnull @NotEmpty public static final String SESSION_NOT_FOUND = "SessionNotFound";
+
/**
* Constructor.
*/
diff --git a/oidc-common-profile-impl/pom.xml b/oidc-common-profile-impl/pom.xml
index d0d8d2f..c2a11f6 100644
--- a/oidc-common-profile-impl/pom.xml
+++ b/oidc-common-profile-impl/pom.xml
@@ -47,6 +47,11 @@
<artifactId>idp-authn-api</artifactId>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>${idp.groupId}</groupId>
+ <artifactId>idp-session-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
<dependency>
<groupId>${shib-profile.groupId}</groupId>
<artifactId>shib-profile-api</artifactId>
diff --git a/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/config/impl/DefaultOIDCLogoutConfiguration.java b/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/config/impl/DefaultOIDCLogoutConfiguration.java
index f4c27f4..1356701 100644
--- a/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/config/impl/DefaultOIDCLogoutConfiguration.java
+++ b/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/config/impl/DefaultOIDCLogoutConfiguration.java
@@ -14,6 +14,7 @@
package net.shibboleth.oidc.profile.config.impl;
+import java.util.function.BiPredicate;
import java.util.function.Function;
import java.util.function.Predicate;
@@ -25,6 +26,7 @@ import org.opensaml.profile.context.ProfileRequestContext;
import com.google.common.base.Predicates;
import net.shibboleth.idp.profile.config.AbstractInterceptorAwareProfileConfiguration;
+import net.shibboleth.idp.session.SPSession;
import net.shibboleth.oidc.profile.config.OIDCLogoutProfileConfiguration;
import net.shibboleth.profile.config.OverriddenIssuerProfileConfiguration;
import net.shibboleth.shared.annotation.constraint.NotEmpty;
@@ -57,6 +59,12 @@ public class DefaultOIDCLogoutConfiguration extends AbstractInterceptorAwareProf
/** Whether to revoke the tokens related to the session to be logged out. */
@Nonnull private Predicate<ProfileRequestContext> revokeTokensPredicate;
+ /** Whether to require the use of id_token_hint in RP-initiated logout parameters. */
+ @Nonnull private Predicate<ProfileRequestContext> requireIdTokenHintPredicate;
+
+ /** Lookup function to the RP-initiated logout's logout_hint parameter. */
+ @Nonnull
+ private Function<ProfileRequestContext,BiPredicate<String,SPSession>> logoutHintMatchingStrategyLookupStrategy;
/**
* Constructor.
*/
@@ -76,6 +84,8 @@ public class DefaultOIDCLogoutConfiguration extends AbstractInterceptorAwareProf
preferFrontChannelPredicate = Predicates.alwaysTrue();
frontChannelSuccessPredicate = Predicates.alwaysFalse();
revokeTokensPredicate = Predicates.alwaysTrue();
+ requireIdTokenHintPredicate = Predicates.alwaysTrue();
+ logoutHintMatchingStrategyLookupStrategy = FunctionSupport.constant((str, session) -> false);
}
@Override @Nullable @NotEmpty
@@ -194,4 +204,58 @@ public class DefaultOIDCLogoutConfiguration extends AbstractInterceptorAwareProf
revokeTokensPredicate =
Constraint.isNotNull(condition, "Front-channel success predicate cannot be null");
}
+
+ @Override
+ public boolean isRequireIdTokenHint(@Nullable final ProfileRequestContext profileRequestContext) {
+ return requireIdTokenHintPredicate.test(profileRequestContext);
+ }
+
+ /**
+ * Set whether to to require the use of id_token_hint in an OIDC RP-initiated logout sequence.
+ *
+ * @param flag flag to set
+ */
+ public void setRequireIdTokenHint(final boolean flag) {
+ requireIdTokenHintPredicate = flag ? Predicates.alwaysTrue() : Predicates.alwaysFalse();
+ }
+
+ /**
+ * Set a condition to determine whether to to require the use of id_token_hint in an OIDC RP-initiated logout
+ * sequence.
+ *
+ * @param condition condition to set
+ */
+ public void setRequireIdTokenHintPredicate(@Nonnull final Predicate<ProfileRequestContext> condition) {
+ requireIdTokenHintPredicate =
+ Constraint.isNotNull(condition, "Require id_token_hint predicate cannot be null");
+ }
+
+ @Override
+ public BiPredicate<String,SPSession> getLogoutHintMatchingStrategy(
+ @Nullable final ProfileRequestContext profileRequestContext) {
+ return logoutHintMatchingStrategyLookupStrategy.apply(profileRequestContext);
+ }
+
+ /**
+ * Set a bi-predicate for matching logout hint to an existing session in an OIDC RP-initiated logout sequence.
+ *
+ * @param strategy bi-predicate to set
+ */
+ public void setLogoutHintMatchingStrategy(@Nonnull final BiPredicate<String,SPSession> strategy) {
+ Constraint.isNotNull(strategy, "Matching strategy cannot be null");
+ logoutHintMatchingStrategyLookupStrategy = FunctionSupport.constant(strategy);
+ }
+
+ /**
+ * Set a lookup strategy for the bi-predicate for matching logout hint to an existing session in an OIDC
+ * RP-initiated logout sequence.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setLogoutHintMatchingStrategyLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,BiPredicate<String,SPSession>> strategy) {
+ logoutHintMatchingStrategyLookupStrategy =
+ Constraint.isNotNull(strategy, "Require id_token_hint predicate 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