[java-idp-oidc] branch main updated: JOIDC-250 - customRedirectUriValidationStrategy for OIDC.Logout
Codeberg
noreply at shibboleth.net
Wed Jun 24 09:30:15 UTC 2026
This is an automated email from the git hooks/post-receive script.
codeberg pushed a commit to branch main
in repository java-idp-oidc.
View the commit online:
https://codeberg.org/Shibboleth/java-idp-oidc/commit/a248d6be6aea8e2cc94977552f041c5508432b81
The following commit(s) were added to refs/heads/main by this push:
new a248d6be JOIDC-250 - customRedirectUriValidationStrategy for OIDC.Logout
a248d6be is described below
commit a248d6be6aea8e2cc94977552f041c5508432b81
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Wed Jun 24 12:23:57 2026 +0300
JOIDC-250 - customRedirectUriValidationStrategy for OIDC.Logout
https://shibboleth.atlassian.net/browse/JOIDC-250
Exploit the new OIDC.Logout option 'customPostLogoutRedirectUriValidationStrategy'.
---
.../impl/ValidatePostLogoutRedirectURI.java | 40 +++++++++++++++++++++-
.../impl/ValidatePostLogoutRedirectURITest.java | 40 +++++++++++++++++++++-
2 files changed, 78 insertions(+), 2 deletions(-)
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/logout/profile/impl/ValidatePostLogoutRedirectURI.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/logout/profile/impl/ValidatePostLogoutRedirectURI.java
index 59ecb3fe..a522f5f5 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/logout/profile/impl/ValidatePostLogoutRedirectURI.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/logout/profile/impl/ValidatePostLogoutRedirectURI.java
@@ -16,6 +16,7 @@ package net.shibboleth.idp.plugin.oidc.op.logout.profile.impl;
import java.net.URI;
import java.util.function.BiPredicate;
+import java.util.function.Function;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -26,12 +27,13 @@ import org.slf4j.Logger;
import net.shibboleth.idp.plugin.oidc.op.messaging.context.OIDCRpInitiatedLogoutContext;
import net.shibboleth.idp.plugin.oidc.op.profile.logic.DefaultPostLogoutRedirectURIValidationPredicate;
+import net.shibboleth.oidc.profile.config.navigate.CustomPostLogoutRedirectUriValidationStrategyLookupFunction;
import net.shibboleth.oidc.profile.core.OidcEventIds;
import net.shibboleth.shared.logic.Constraint;
import net.shibboleth.shared.primitive.LoggerFactory;
/**
- * Action that validates post redirect URI is expected if it's being requested.
+ * Action that validates post logout redirect URI is expected if it's being requested.
*/
public class ValidatePostLogoutRedirectURI extends AbstractOIDCRpInitiatedLogoutAction {
@@ -41,6 +43,10 @@ public class ValidatePostLogoutRedirectURI extends AbstractOIDCRpInitiatedLogout
/** Strategy used to validate the post logout redirect URIs. */
@Nonnull private BiPredicate<ProfileRequestContext, URI> redirectURIValidationStrategy;
+ /** Strategy to obtain custom post logout redirect URI validation strategy. */
+ @Nonnull private Function<ProfileRequestContext,BiPredicate<URI, ProfileRequestContext>>
+ customPostLogoutRedirectUriValidationStrategyLookupStrategy;
+
/** The redirect URI to be validated. */
@Nullable private URI requestedRedirectURI;
@@ -49,6 +55,8 @@ public class ValidatePostLogoutRedirectURI extends AbstractOIDCRpInitiatedLogout
*/
public ValidatePostLogoutRedirectURI() {
redirectURIValidationStrategy = new DefaultPostLogoutRedirectURIValidationPredicate();
+ customPostLogoutRedirectUriValidationStrategyLookupStrategy =
+ new CustomPostLogoutRedirectUriValidationStrategyLookupFunction();
}
/**
@@ -62,6 +70,22 @@ public class ValidatePostLogoutRedirectURI extends AbstractOIDCRpInitiatedLogout
Constraint.isNotNull(strategy, "RedirectURILookupStrategy lookup strategy cannot be null");
}
+ /**
+ * Set the strategy to obtain custom post logout redirect URI validation strategy. If a non-null value is resolved
+ * via strategy, the bi-predicate will be used for validating the incoming request URI value.
+ *
+ * @param strategy lookup strategy
+ *
+ * @since 4.4.0
+ */
+ public void setCustomPostLogoutRedirectUriValidationStrategyLookupStrategy(@Nonnull
+ final Function<ProfileRequestContext,BiPredicate<URI, ProfileRequestContext>> strategy) {
+ checkSetterPreconditions();
+
+ customPostLogoutRedirectUriValidationStrategyLookupStrategy = Constraint.isNotNull(strategy,
+ "Custom post logout redirect URI validation lookup strategy cannot be null");
+ }
+
/** {@inheritDoc} */
@Override
protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
@@ -84,6 +108,20 @@ public class ValidatePostLogoutRedirectURI extends AbstractOIDCRpInitiatedLogout
/** {@inheritDoc} */
@Override
protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ final BiPredicate<URI, ProfileRequestContext> customPostLogoutRedirectUriValidationStrategy =
+ customPostLogoutRedirectUriValidationStrategyLookupStrategy.apply(profileRequestContext);
+ if (customPostLogoutRedirectUriValidationStrategy != null) {
+ if (!customPostLogoutRedirectUriValidationStrategy.test(requestedRedirectURI, profileRequestContext)) {
+ log.warn("{} Custom post logout redirect URI validation failed for {}", getLogPrefix(),
+ requestedRedirectURI);
+ ActionSupport.buildEvent(profileRequestContext, OidcEventIds.INVALID_REDIRECT_URI);
+ } else {
+ log.debug("{} Custom post logout redirect URI validation successful for {}", getLogPrefix(),
+ requestedRedirectURI);
+ }
+ return;
+ }
+
if (!redirectURIValidationStrategy.test(profileRequestContext, requestedRedirectURI)) {
log.warn("{} Post logout redirection URI {} did not pass the validation", getLogPrefix(),
requestedRedirectURI);
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/logout/profile/impl/ValidatePostLogoutRedirectURITest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/logout/profile/impl/ValidatePostLogoutRedirectURITest.java
index 530d3e47..bf1fd2e3 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/logout/profile/impl/ValidatePostLogoutRedirectURITest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/logout/profile/impl/ValidatePostLogoutRedirectURITest.java
@@ -17,7 +17,10 @@ package net.shibboleth.idp.plugin.oidc.op.logout.profile.impl;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Set;
+import java.util.function.BiPredicate;
+import java.util.function.Function;
+import org.opensaml.profile.context.ProfileRequestContext;
import org.testng.Assert;
import org.testng.annotations.Test;
@@ -37,7 +40,15 @@ public class ValidatePostLogoutRedirectURITest
@Override
protected ValidatePostLogoutRedirectURI constructAction() {
+ return constructAction(null);
+ }
+
+ protected ValidatePostLogoutRedirectURI constructAction(
+ final Function<ProfileRequestContext,BiPredicate<URI, ProfileRequestContext>> customStrategy) {
final ValidatePostLogoutRedirectURI action = new ValidatePostLogoutRedirectURI();
+ if (customStrategy != null) {
+ action.setCustomPostLogoutRedirectUriValidationStrategyLookupStrategy(customStrategy);
+ }
try {
action.initialize();
} catch (final ComponentInitializationException e) {
@@ -45,7 +56,7 @@ public class ValidatePostLogoutRedirectURITest
}
return action;
}
-
+
@Test
public void noRequestedPostLogoutRedirectURis() {
ActionTestingSupport.assertProceedEvent(action.execute(requestContext));
@@ -57,6 +68,13 @@ public class ValidatePostLogoutRedirectURITest
ActionTestingSupport.assertEvent(action.execute(requestContext), OidcEventIds.INVALID_REDIRECT_URI);
}
+ @Test
+ public void noRegisteredPostLogoutRedirectURis_overrideWithCustomPredicate() {
+ action = constructAction(p -> ((prc, uri) -> true));
+ rpInitiatedLogoutContext.setPostLogoutRedirectUri(mockPostLogoutRedirectUri());
+ ActionTestingSupport.assertProceedEvent(action.execute(requestContext));
+ }
+
@Test
public void noMatchingRegisteredPostLogoutRedirectURis() throws URISyntaxException {
final OIDCClientMetadata metadata = new OIDCClientMetadata();
@@ -66,6 +84,16 @@ public class ValidatePostLogoutRedirectURITest
ActionTestingSupport.assertEvent(action.execute(requestContext), OidcEventIds.INVALID_REDIRECT_URI);
}
+ @Test
+ public void noMatchingRegisteredPostLogoutRedirectURis_overrideWithCustomPredicate() throws URISyntaxException {
+ action = constructAction(p -> ((prc, uri) -> true));
+ final OIDCClientMetadata metadata = new OIDCClientMetadata();
+ metadata.setPostLogoutRedirectionURIs(Set.of(new URI("https://rp.example.com/notMatching")));
+ oidcMetadataContext.setClientInformation(new OIDCClientInformation(new ClientID("mockClientId"), metadata));
+ rpInitiatedLogoutContext.setPostLogoutRedirectUri(mockPostLogoutRedirectUri());
+ ActionTestingSupport.assertProceedEvent(action.execute(requestContext));
+ }
+
@Test
public void matchingRegisteredPostLogoutRedirectURis() {
final OIDCClientMetadata metadata = new OIDCClientMetadata();
@@ -75,6 +103,16 @@ public class ValidatePostLogoutRedirectURITest
ActionTestingSupport.assertProceedEvent(action.execute(requestContext));
}
+ @Test
+ public void matchingRegisteredPostLogoutRedirectURis_overrideWithCustomPredicate() {
+ action = constructAction(p -> ((prc, uri) -> false));
+ final OIDCClientMetadata metadata = new OIDCClientMetadata();
+ metadata.setPostLogoutRedirectionURIs(Set.of(mockPostLogoutRedirectUri()));
+ oidcMetadataContext.setClientInformation(new OIDCClientInformation(new ClientID("mockClientId"), metadata));
+ rpInitiatedLogoutContext.setPostLogoutRedirectUri(mockPostLogoutRedirectUri());
+ ActionTestingSupport.assertEvent(action.execute(requestContext), OidcEventIds.INVALID_REDIRECT_URI);
+ }
+
protected URI mockPostLogoutRedirectUri() {
try {
return new URI("https://rp.example.com/postLogout");
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list