[java-idp-oidc] branch main updated: JOIDC-13 - Support for OIDC Logout

Henri Mikkonen henri.mikkonen at iki.fi
Fri Mar 15 11:16:10 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=9118d36edad6b085e1353b37c8057398dbbeb59f

The following commit(s) were added to refs/heads/main by this push:
     new 9118d36e JOIDC-13 - Support for OIDC Logout
9118d36e is described below

commit 9118d36edad6b085e1353b37c8057398dbbeb59f
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Fri Mar 15 13:14:05 2024 +0200

    JOIDC-13 - Support for OIDC Logout
    
    https://shibboleth.atlassian.net/browse/JOIDC-13
    
    Updated dynamic client registration to support the logout parameters:
    
    - post_logout_redirect_uris
    - frontchannel_logout_session_required
    - frontchannel_logout_uri
    - backchannel_logout_session_required
    - backchannel_logout_uri
---
 .../impl/AddLogoutParametersToClientMetadata.java  | 39 ++++++++++
 .../idp/flows/oidc/register/register-beans.xml     |  3 +
 .../idp/flows/oidc/register/register-flow.xml      |  1 +
 .../oidc/op/profile/flow/RegistrationFlowTest.java | 41 +++++++++++
 .../AddLogoutParametersToClientMetadataTest.java   | 84 ++++++++++++++++++++++
 5 files changed, 168 insertions(+)

diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/AddLogoutParametersToClientMetadata.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/AddLogoutParametersToClientMetadata.java
new file mode 100644
index 00000000..9ea79ddd
--- /dev/null
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/AddLogoutParametersToClientMetadata.java
@@ -0,0 +1,39 @@
+/*
+ * 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.idp.plugin.oidc.op.profile.impl;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import com.nimbusds.openid.connect.sdk.rp.OIDCClientMetadata;
+
+/**
+ * Adds the parameters related to OIDC logout to the output {@link OIDCClientMetadata}. The values are expected to be
+ * already validated.
+ */
+public class AddLogoutParametersToClientMetadata extends AbstractOIDCClientMetadataPopulationAction {
+
+    /** {@inheritDoc} */
+    @Override
+    protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+        getOutputMetadata().setPostLogoutRedirectionURIs(getInputMetadata().getPostLogoutRedirectionURIs());
+        getOutputMetadata().setBackChannelLogoutURI(getInputMetadata().getBackChannelLogoutURI());
+        getOutputMetadata().setFrontChannelLogoutURI(getInputMetadata().getFrontChannelLogoutURI());
+        getOutputMetadata().requiresBackChannelLogoutSession(getInputMetadata().requiresBackChannelLogoutSession());
+        getOutputMetadata().requiresFrontChannelLogoutSession(getInputMetadata().requiresFrontChannelLogoutSession());
+    }
+
+}
\ No newline at end of file
diff --git a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/register/register-beans.xml b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/register/register-beans.xml
index 63e7af9b..e4cabc80 100644
--- a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/register/register-beans.xml
+++ b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/register/register-beans.xml
@@ -161,6 +161,9 @@
     <bean id="AddRequestUrisToClientMetadata" scope="prototype"
         class="net.shibboleth.idp.plugin.oidc.op.profile.impl.AddRequestUrisToClientMetadata" />
 
+    <bean id="AddLogoutParametersToClientMetadata" scope="prototype"
+        class="net.shibboleth.idp.plugin.oidc.op.profile.impl.AddLogoutParametersToClientMetadata" />
+
     <bean id="AddRemainingClaimsToClientMetadata" scope="prototype"
         class="net.shibboleth.idp.plugin.oidc.op.profile.impl.AddRemainingClaimsToClientMetadata" />
 
diff --git a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/register/register-flow.xml b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/register/register-flow.xml
index c74333f8..5edac98d 100644
--- a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/register/register-flow.xml
+++ b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/register/register-flow.xml
@@ -62,6 +62,7 @@
         <evaluate expression="AddSecurityConfigurationToClientMetadata" />
         <evaluate expression="AddRequestObjectSecurityConfigurationToClientMetadata" />
         <evaluate expression="AddRequestUrisToClientMetadata" />
+        <evaluate expression="AddLogoutParametersToClientMetadata" />
         <evaluate expression="AddRemainingClaimsToClientMetadata" />
         <evaluate expression="'proceed'" />
         <transition on="proceed" to="PopulateOutboundInterceptContext" />
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/RegistrationFlowTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/RegistrationFlowTest.java
index d53f578a..27f71b34 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/RegistrationFlowTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/RegistrationFlowTest.java
@@ -118,6 +118,47 @@ public class RegistrationFlowTest extends AbstractOidcFlowTest {
         Assert.assertTrue(metadata.getRedirectionURIStrings().contains(redirectUri));
     }
 
+    @Test
+    public void testUnauthenticated_invalidPostLogout() throws Exception {
+        final String requestUri = "https://client.example.org/rf.txt#qpXaRLh_n93TTR9F252ValdatUQvQiJi5BDub2BeznA";
+        setJsonRequest("POST", "{ \"redirect_uris\":[\"" + redirectUri + "\"], \"request_uris\":[\"" + requestUri + "\"]," 
+                + "\"post_logout_redirect_uris\":[\"^http://invalid_url\"]}");
+        final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+        assertErrorCode(result, "invalid_client_metadata");
+    }
+
+    @Test
+    public void testUnauthenticated_successWithLogoutParams() throws Exception {
+        final String requestUri = "https://client.example.org/rf.txt#qpXaRLh_n93TTR9F252ValdatUQvQiJi5BDub2BeznA";
+        setJsonRequest("POST", "{ \"redirect_uris\":[\"" + redirectUri + "\"], \"request_uris\":[\"" + requestUri + "\"]," 
+                + "\"post_logout_redirect_uris\":[\"https://example.org/postLogout1\",\"https://example.org/postLogout2\"],"
+                + "\"frontchannel_logout_session_required\":true,"
+                + "\"frontchannel_logout_uri\":\"https://example.org/frontChannel\","
+                + "\"backchannel_logout_session_required\":true,"
+                + "\"backchannel_logout_uri\":\"https://example.org/backChannel\"}");
+        final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+        final OIDCClientInformationResponse parsedResponse =
+                parseSuccessResponse(result, OIDCClientInformationResponse.class);
+        final OIDCClientInformation clientInfo = parsedResponse.getOIDCClientInformation();
+        final OIDCClientMetadata metadata = clientInfo.getOIDCMetadata();
+        final String record = storageService.read(BaseStorageServiceClientInformationComponent.CONTEXT_NAME, 
+                clientInfo.getID().toString()).getValue();
+        Assert.assertNotNull(record);
+        final JSONParser parser = new JSONParser(JSONParser.DEFAULT_PERMISSIVE_MODE);
+        final OIDCClientInformation storedInfo = OIDCClientInformation.parse((JSONObject) parser.parse(record));
+        Assert.assertEquals(storedInfo.getID(), clientInfo.getID());
+        Assert.assertEquals(storedInfo.getSecret(), clientInfo.getSecret());
+        Assert.assertEquals(storedInfo.getOIDCMetadata().getRedirectionURIStrings(), metadata.getRedirectionURIStrings());
+        Assert.assertEquals(storedInfo.getOIDCMetadata().getRequestObjectURIs(), Set.of(new URI(requestUri)));
+        Assert.assertTrue(metadata.getRedirectionURIStrings().contains(redirectUri));
+        Assert.assertEquals(storedInfo.getOIDCMetadata().getPostLogoutRedirectionURIs(),
+                Set.of(new URI("https://example.org/postLogout1"), new URI("https://example.org/postLogout2")));
+        Assert.assertEquals(storedInfo.getOIDCMetadata().getFrontChannelLogoutURI(), new URI("https://example.org/frontChannel"));
+        Assert.assertEquals(storedInfo.getOIDCMetadata().getBackChannelLogoutURI(), new URI("https://example.org/backChannel"));
+        Assert.assertTrue(storedInfo.getOIDCMetadata().requiresFrontChannelLogoutSession());
+        Assert.assertTrue(storedInfo.getOIDCMetadata().requiresBackChannelLogoutSession());
+    }
+
     @Test
     public void testAccessToken_nonCompliantWithProfilePolicy1() throws Exception {
         setJsonRequest("POST", "{ \"redirect_uris\":[\"" + redirectUri + "\"] }");
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/AddLogoutParametersToClientMetadataTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/AddLogoutParametersToClientMetadataTest.java
new file mode 100644
index 00000000..577524a1
--- /dev/null
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/AddLogoutParametersToClientMetadataTest.java
@@ -0,0 +1,84 @@
+/*
+ * 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.idp.plugin.oidc.op.profile.impl;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Set;
+
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.nimbusds.openid.connect.sdk.rp.OIDCClientMetadata;
+
+import net.shibboleth.shared.component.ComponentInitializationException;
+
+/**
+ * Unit tests for {@link AddLogoutParametersToClientMetadata}.
+ */
+public class AddLogoutParametersToClientMetadataTest extends BaseOIDCClientMetadataPopulationTest {
+
+    AddLogoutParametersToClientMetadata action;
+    
+    @BeforeMethod
+    public void setUp() throws ComponentInitializationException, URISyntaxException {
+        action = new AddLogoutParametersToClientMetadata();
+        action.initialize();
+    }
+    
+    @Override
+    protected AbstractOIDCClientMetadataPopulationAction constructAction() {
+        return new AddLogoutParametersToClientMetadata();
+    }
+
+    @Test
+    public void testPostLogoutUriPopulation() throws ComponentInitializationException, URISyntaxException {
+        final URI postLogout1 = new URI("https://example.org/postLogout1");
+        final OIDCClientMetadata input = new OIDCClientMetadata();
+        input.setPostLogoutRedirectionURIs(Set.of(postLogout1));
+        final OIDCClientMetadata output = new OIDCClientMetadata();
+        setUpContext(input, output);
+        Assert.assertNull(action.execute(requestCtx));
+        Assert.assertEquals(output.getPostLogoutRedirectionURIs(), Set.of(postLogout1));
+        Assert.assertNull(output.getFrontChannelLogoutURI());
+        Assert.assertNull(output.getBackChannelLogoutURI());
+        Assert.assertFalse(output.requiresFrontChannelLogoutSession());
+        Assert.assertFalse(output.requiresBackChannelLogoutSession());
+    }
+
+    @Test
+    public void testFullPopulation() throws ComponentInitializationException, URISyntaxException {
+        final URI postLogout1 = new URI("https://example.org/postLogout1");
+        final URI postLogout2 = new URI("https://example.org/postLogout2");
+        final URI frontChannel = new URI("https://example.org/frontChannel");
+        final URI backChannel = new URI("https://example.org/backChannel");
+        final OIDCClientMetadata input = new OIDCClientMetadata();
+        input.setPostLogoutRedirectionURIs(Set.of(postLogout1, postLogout2));
+        input.setFrontChannelLogoutURI(frontChannel);
+        input.setBackChannelLogoutURI(backChannel);
+        input.requiresFrontChannelLogoutSession(true);
+        input.requiresBackChannelLogoutSession(true);
+        final OIDCClientMetadata output = new OIDCClientMetadata();
+        setUpContext(input, output);
+        Assert.assertNull(action.execute(requestCtx));
+        Assert.assertEquals(output.getPostLogoutRedirectionURIs(), Set.of(postLogout1, postLogout2));
+        Assert.assertEquals(output.getFrontChannelLogoutURI(), frontChannel);
+        Assert.assertEquals(output.getBackChannelLogoutURI(), backChannel);
+        Assert.assertTrue(output.requiresFrontChannelLogoutSession());
+        Assert.assertTrue(output.requiresBackChannelLogoutSession());
+    }
+
+}

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


More information about the commits mailing list