[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