[java-oidc-common] branch main updated: JCOMOIDC-34 - Authentication request message encoder factory
Phil Smart
philip.smart at jisc.ac.uk
Fri Jan 7 14:30:45 UTC 2022
This is an automated email from the git hooks/post-receive script.
philsmart 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=9a24d04d16d316907922cf65fc55d9500b5cafdb
The following commit(s) were added to refs/heads/main by this push:
new 9a24d04 JCOMOIDC-34 - Authentication request message encoder factory
9a24d04 is described below
commit 9a24d04d16d316907922cf65fc55d9500b5cafdb
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Fri Jan 7 14:30:39 2022 +0000
JCOMOIDC-34 - Authentication request message encoder factory
- Add a factory for returning a message encoder based on the request
method in the profile configuration.
https://shibboleth.atlassian.net/browse/JCOMOIDC-34
---
...AuthenticationRequestMessageEncoderFactory.java | 107 +++++++++++++
.../shibboleth/oidc/profile/impl/package-info.java | 21 +++
...enticationRequestMessageEncoderFactoryTest.java | 173 +++++++++++++++++++++
3 files changed, 301 insertions(+)
diff --git a/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/impl/AuthenticationRequestMessageEncoderFactory.java b/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/impl/AuthenticationRequestMessageEncoderFactory.java
new file mode 100644
index 0000000..8fdd604
--- /dev/null
+++ b/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/impl/AuthenticationRequestMessageEncoderFactory.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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.impl;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.ThreadSafe;
+
+import org.opensaml.messaging.encoder.MessageEncoder;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.shibboleth.idp.profile.context.RelyingPartyContext;
+import net.shibboleth.oidc.profile.config.OIDCAuthorizationConfiguration;
+import net.shibboleth.oidc.profile.config.OIDCAuthorizationConfiguration.OIDCHttpRequestMethod;
+import net.shibboleth.oidc.profile.encoder.OIDCMessageEncoder;
+import net.shibboleth.utilities.java.support.annotation.ParameterName;
+import net.shibboleth.utilities.java.support.annotation.constraint.NotLive;
+import net.shibboleth.utilities.java.support.annotation.constraint.Unmodifiable;
+import net.shibboleth.utilities.java.support.component.AbstractInitializableComponent;
+
+/**
+ * Message encoder factory function that returns the first encoder suitable for the given request method found in the
+ * profile configuration.
+ */
+ at ThreadSafe
+public class AuthenticationRequestMessageEncoderFactory extends AbstractInitializableComponent
+ implements Function<ProfileRequestContext, MessageEncoder> {
+
+ /** Class logger. */
+ @Nonnull
+ private final Logger log = LoggerFactory.getLogger(AuthenticationRequestMessageEncoderFactory.class);
+
+ /** The list of message encoders to choose from. */
+ @Nonnull @Unmodifiable @NotLive private final List<OIDCMessageEncoder> encoders;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param encodersToUse the list of possible encoders to use.
+ */
+ public AuthenticationRequestMessageEncoderFactory(
+ @Nullable @ParameterName(name = "encoders") final List<OIDCMessageEncoder> encodersToUse) {
+ if (encodersToUse == null) {
+ encoders = Collections.emptyList();
+ } else {
+ encoders = Collections.unmodifiableList(encodersToUse);
+ }
+ }
+
+ @Override
+ @Nullable public MessageEncoder apply(@Nonnull final ProfileRequestContext profileRequestContext) {
+
+ final RelyingPartyContext rpCtx = profileRequestContext.getSubcontext(RelyingPartyContext.class);
+ OIDCAuthorizationConfiguration profileConfiguration = null;
+
+ if (rpCtx != null && rpCtx.getProfileConfig() instanceof OIDCAuthorizationConfiguration) {
+ profileConfiguration = (OIDCAuthorizationConfiguration) rpCtx.getProfileConfig();
+ }
+ if (profileConfiguration == null) {
+ log.warn("OIDCAuthorizationConfiguration not found, no encoders to lookup");
+ return null;
+ }
+
+ final OIDCHttpRequestMethod requestMethodFromConfig =
+ profileConfiguration.getHttpRequestMethod(profileRequestContext);
+
+ if (requestMethodFromConfig == null) {
+ log.warn("Authentication request method not found on profile, no encoders to lookup");
+ return null;
+ }
+
+ final Optional<OIDCMessageEncoder> encoder =
+ encoders.stream().filter(enc -> enc.test(requestMethodFromConfig)).findFirst();
+ if (encoder.isPresent()) {
+ log.trace("Returning OIDC message encoder of type '{}'", encoder.get().getClass());
+ } else {
+ log.warn("No message encoder was found for authentication request method type '{}'",
+ requestMethodFromConfig);
+ }
+
+ return encoder.orElse(null);
+ }
+
+}
diff --git a/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/impl/package-info.java b/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/impl/package-info.java
new file mode 100644
index 0000000..e1fd983
--- /dev/null
+++ b/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/impl/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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.
+ */
+
+/**
+ * OIDC profile implementation classes.
+ */
+package net.shibboleth.oidc.profile.impl;
\ No newline at end of file
diff --git a/oidc-common-profile-impl/src/test/java/net/shibboleth/oidc/profile/impl/AuthenticationRequestMessageEncoderFactoryTest.java b/oidc-common-profile-impl/src/test/java/net/shibboleth/oidc/profile/impl/AuthenticationRequestMessageEncoderFactoryTest.java
new file mode 100644
index 0000000..76485ac
--- /dev/null
+++ b/oidc-common-profile-impl/src/test/java/net/shibboleth/oidc/profile/impl/AuthenticationRequestMessageEncoderFactoryTest.java
@@ -0,0 +1,173 @@
+package net.shibboleth.oidc.profile.impl;
+
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+import java.util.List;
+
+import org.opensaml.messaging.encoder.MessageEncoder;
+import org.opensaml.messaging.encoder.MessageEncodingException;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.testng.annotations.Test;
+
+import net.shibboleth.idp.profile.context.RelyingPartyContext;
+import net.shibboleth.oidc.profile.config.OIDCAuthorizationConfiguration;
+import net.shibboleth.oidc.profile.config.OIDCAuthorizationConfiguration.OIDCHttpRequestMethod;
+import net.shibboleth.oidc.profile.encoder.OIDCMessageEncoder;
+import net.shibboleth.oidc.profile.encoder.impl.AbstractOIDCMessageEncoder;
+
+/** Test of the AuthenticationRequestMessageEncoderFactory class.*/
+public class AuthenticationRequestMessageEncoderFactoryTest {
+
+ /** The factory to test.*/
+ private AuthenticationRequestMessageEncoderFactory factory;
+
+
+ @Test
+ public void testNoEncoders() {
+ factory = new AuthenticationRequestMessageEncoderFactory(null);
+ final ProfileRequestContext prc = new ProfileRequestContext();
+ final MessageEncoder encoder = factory.apply(prc);
+ //should be null
+ assertNull(encoder);
+ }
+
+ @Test
+ public void testPostEncoder() {
+ final OIDCMessageEncoder mockPostEncoder = new AbstractOIDCMessageEncoder() {
+
+ @Override
+ public boolean test(final OIDCHttpRequestMethod method) {
+ if (method == OIDCHttpRequestMethod.POST) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ protected void doEncode() throws MessageEncodingException {
+ //no-op
+ }
+ };
+ factory = new AuthenticationRequestMessageEncoderFactory(List.of(mockPostEncoder));
+
+ final ProfileRequestContext prc = new ProfileRequestContext();
+ // mock a profile config to request form POST serialization
+ final OIDCAuthorizationConfiguration config = new OIDCAuthorizationConfiguration();
+ config.setHttpRequestMethodLookupStrategy(rc -> OIDCHttpRequestMethod.POST);
+ final RelyingPartyContext rpCtx = prc.getSubcontext(RelyingPartyContext.class, true);
+ rpCtx.setProfileConfig(config);
+
+ final MessageEncoder encoder = factory.apply(prc);
+ assertNotNull(encoder);
+ assertTrue(encoder == mockPostEncoder);
+ }
+
+ @Test
+ public void testGetEncoder() {
+ final OIDCMessageEncoder mockGetEncoder = new AbstractOIDCMessageEncoder() {
+
+ @Override
+ public boolean test(final OIDCHttpRequestMethod method) {
+ if (method == OIDCHttpRequestMethod.GET) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ protected void doEncode() throws MessageEncodingException {
+ //no-op
+ }
+ };
+ factory = new AuthenticationRequestMessageEncoderFactory(List.of(mockGetEncoder));
+
+ final ProfileRequestContext prc = new ProfileRequestContext();
+ // mock a profile config to request form POST serialization
+ final OIDCAuthorizationConfiguration config = new OIDCAuthorizationConfiguration();
+ config.setHttpRequestMethodLookupStrategy(rc -> OIDCHttpRequestMethod.GET);
+ final RelyingPartyContext rpCtx = prc.getSubcontext(RelyingPartyContext.class, true);
+ rpCtx.setProfileConfig(config);
+
+ final MessageEncoder encoder = factory.apply(prc);
+ assertNotNull(encoder);
+ assertTrue(encoder == mockGetEncoder);
+ }
+
+ /* Ask for POST, but only GET type registered.*/
+ @Test
+ public void testNoAvailableEncoder() {
+ final OIDCMessageEncoder mockGetEncoder = new AbstractOIDCMessageEncoder() {
+
+ @Override
+ public boolean test(final OIDCHttpRequestMethod method) {
+ if (method == OIDCHttpRequestMethod.GET) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ protected void doEncode() throws MessageEncodingException {
+ //no-op
+ }
+ };
+ factory = new AuthenticationRequestMessageEncoderFactory(List.of(mockGetEncoder));
+
+ final ProfileRequestContext prc = new ProfileRequestContext();
+ // mock a profile config to request form POST serialization
+ final OIDCAuthorizationConfiguration config = new OIDCAuthorizationConfiguration();
+ config.setHttpRequestMethodLookupStrategy(rc -> OIDCHttpRequestMethod.POST);
+ final RelyingPartyContext rpCtx = prc.getSubcontext(RelyingPartyContext.class, true);
+ rpCtx.setProfileConfig(config);
+
+ final MessageEncoder encoder = factory.apply(prc);
+ //should be null
+ assertNull(encoder);
+
+ }
+
+ @Test
+ public void testNullRequestMethod() {
+ factory = new AuthenticationRequestMessageEncoderFactory(null);
+
+ final ProfileRequestContext prc = new ProfileRequestContext();
+ // mock a profile config to request form POST serialization
+ final OIDCAuthorizationConfiguration config = new OIDCAuthorizationConfiguration();
+ config.setHttpRequestMethodLookupStrategy(rc -> null);
+ final RelyingPartyContext rpCtx = prc.getSubcontext(RelyingPartyContext.class, true);
+ rpCtx.setProfileConfig(config);
+
+ final MessageEncoder encoder = factory.apply(prc);
+ //should be null
+ assertNull(encoder);
+
+ }
+
+ @Test
+ public void testNullProfileConfiguration() {
+ factory = new AuthenticationRequestMessageEncoderFactory(null);
+
+ final ProfileRequestContext prc = new ProfileRequestContext();
+ final RelyingPartyContext rpCtx = prc.getSubcontext(RelyingPartyContext.class, true);
+ rpCtx.setProfileConfig(null);
+
+ final MessageEncoder encoder = factory.apply(prc);
+ //should be null
+ assertNull(encoder);
+
+ }
+
+ @Test
+ public void testNullRelyingPartyContext() {
+ factory = new AuthenticationRequestMessageEncoderFactory(null);
+
+ final ProfileRequestContext prc = new ProfileRequestContext();
+ final MessageEncoder encoder = factory.apply(prc);
+ //should be null
+ assertNull(encoder);
+
+ }
+
+}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list