[java-oidc-common] branch main updated: JCOMOIDC-39 - Add OIDC authentication response message decoders
Phil Smart
philip.smart at jisc.ac.uk
Fri Jan 21 14:24:56 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=34030540e7adb07e8dc7558e8f44495506724b7e
The following commit(s) were added to refs/heads/main by this push:
new 3403054 JCOMOIDC-39 - Add OIDC authentication response message decoders
3403054 is described below
commit 34030540e7adb07e8dc7558e8f44495506724b7e
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Fri Jan 21 14:24:49 2022 +0000
JCOMOIDC-39 - Add OIDC authentication response message decoders
- Add form_post and query decoders.
- Uses Nimbus to parse the response into an AuthenticationResponse
https://shibboleth.atlassian.net/browse/JCOMOIDC-39
---
.../oidc/profile/decoding/OIDCMessageDecoder.java | 25 ++++++++
.../impl/HTTPPostAuthnResponseDecoder.java | 72 +++++++++++++++++++++
.../impl/HTTPRedirectAuthnResponseDecoder.java | 72 +++++++++++++++++++++
.../impl/HTTPPostAuthnResponseDecoderTest.java | 74 ++++++++++++++++++++++
.../impl/HTTPRedirectAuthnResponseDecoderTest.java | 74 ++++++++++++++++++++++
5 files changed, 317 insertions(+)
diff --git a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/decoding/OIDCMessageDecoder.java b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/decoding/OIDCMessageDecoder.java
new file mode 100644
index 0000000..8ee17b0
--- /dev/null
+++ b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/decoding/OIDCMessageDecoder.java
@@ -0,0 +1,25 @@
+/*
+ * 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.decoding;
+
+import org.opensaml.messaging.decoder.MessageDecoder;
+
+/** Marker interface for OIDC Message Decoders.*/
+public interface OIDCMessageDecoder extends MessageDecoder {
+
+}
diff --git a/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/decoding/impl/HTTPPostAuthnResponseDecoder.java b/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/decoding/impl/HTTPPostAuthnResponseDecoder.java
new file mode 100644
index 0000000..278b49d
--- /dev/null
+++ b/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/decoding/impl/HTTPPostAuthnResponseDecoder.java
@@ -0,0 +1,72 @@
+/*
+ * 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.decoding.impl;
+
+import java.io.IOException;
+
+import javax.annotation.Nonnull;
+import javax.servlet.http.HttpServletRequest;
+
+import org.opensaml.messaging.context.MessageContext;
+import org.opensaml.messaging.decoder.MessageDecoder;
+import org.opensaml.messaging.decoder.MessageDecodingException;
+import org.opensaml.messaging.decoder.servlet.AbstractHttpServletRequestMessageDecoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.nimbusds.oauth2.sdk.ParseException;
+import com.nimbusds.oauth2.sdk.http.ServletUtils;
+import com.nimbusds.openid.connect.sdk.AuthenticationResponse;
+import com.nimbusds.openid.connect.sdk.AuthenticationResponseParser;
+
+import net.shibboleth.oidc.profile.decoding.OIDCMessageDecoder;
+
+/**
+ * A {@link MessageDecoder message decoder} that decodes an incoming {@link AuthenticationResponse}
+ * when using a form_post response_type.
+ */
+//TODO this is identical to the HTTPRedirectAuthnDecoder because it uses the Nimbus parser.
+// do we leave as a placeholder for when we create our own decoders?
+public class HTTPPostAuthnResponseDecoder extends AbstractHttpServletRequestMessageDecoder implements OIDCMessageDecoder {
+
+ /** Class logger. */
+ @Nonnull
+ private final Logger log = LoggerFactory.getLogger(HTTPPostAuthnResponseDecoder.class);
+
+ @Override
+ protected void doDecode() throws MessageDecodingException {
+
+ log.trace("Decoding incomming 'form_post' authentication response");
+
+ final MessageContext messageContext = new MessageContext();
+ final HttpServletRequest request = getHttpServletRequest();
+
+ if (!"POST".equalsIgnoreCase(request.getMethod())) {
+ throw new MessageDecodingException("This message decoder only supports the HTTP POST method");
+ }
+
+ try {
+ final AuthenticationResponse inboundMessage =
+ AuthenticationResponseParser.parse(ServletUtils.createHTTPRequest(request));
+ messageContext.setMessage(inboundMessage);
+ } catch (ParseException | IOException e) {
+ log.error("Unable to parse incomming authentication response",e);
+ }
+ setMessageContext(messageContext);
+ }
+}
diff --git a/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/decoding/impl/HTTPRedirectAuthnResponseDecoder.java b/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/decoding/impl/HTTPRedirectAuthnResponseDecoder.java
new file mode 100644
index 0000000..faa2a8c
--- /dev/null
+++ b/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/decoding/impl/HTTPRedirectAuthnResponseDecoder.java
@@ -0,0 +1,72 @@
+/*
+ * 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.decoding.impl;
+
+import java.io.IOException;
+
+import javax.annotation.Nonnull;
+import javax.servlet.http.HttpServletRequest;
+
+import org.opensaml.messaging.context.MessageContext;
+import org.opensaml.messaging.decoder.MessageDecoder;
+import org.opensaml.messaging.decoder.MessageDecodingException;
+import org.opensaml.messaging.decoder.servlet.AbstractHttpServletRequestMessageDecoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.nimbusds.oauth2.sdk.ParseException;
+import com.nimbusds.oauth2.sdk.http.ServletUtils;
+import com.nimbusds.openid.connect.sdk.AuthenticationResponse;
+import com.nimbusds.openid.connect.sdk.AuthenticationResponseParser;
+
+import net.shibboleth.oidc.profile.decoding.OIDCMessageDecoder;
+
+
+/**
+ * A {@link MessageDecoder message decoder} that decodes an incoming {@link AuthenticationResponse}
+ * when using a query response_mode.
+ */
+//TODO this is identical to the HTTPPostAuthnDecoder because it uses the Nimbus parser.
+public class HTTPRedirectAuthnResponseDecoder extends AbstractHttpServletRequestMessageDecoder implements OIDCMessageDecoder {
+
+ /** Class logger. */
+ @Nonnull
+ private final Logger log = LoggerFactory.getLogger(HTTPRedirectAuthnResponseDecoder.class);
+
+ @Override
+ protected void doDecode() throws MessageDecodingException {
+
+ log.trace("Decoding incomming 'query' authentication response");
+
+ final MessageContext messageContext = new MessageContext();
+ final HttpServletRequest request = getHttpServletRequest();
+
+ if (!"GET".equalsIgnoreCase(request.getMethod())) {
+ throw new MessageDecodingException("This message decoder only supports the HTTP GET method");
+ }
+
+ try {
+ final AuthenticationResponse inboundMessage =
+ AuthenticationResponseParser.parse(ServletUtils.createHTTPRequest(request));
+ messageContext.setMessage(inboundMessage);
+ } catch (ParseException | IOException e) {
+ log.error("Unable to parse incomming authentication response",e);
+ }
+ setMessageContext(messageContext);
+ }
+}
diff --git a/oidc-common-profile-impl/src/test/java/net/shibboleth/oidc/profile/decoding/impl/HTTPPostAuthnResponseDecoderTest.java b/oidc-common-profile-impl/src/test/java/net/shibboleth/oidc/profile/decoding/impl/HTTPPostAuthnResponseDecoderTest.java
new file mode 100644
index 0000000..50b3431
--- /dev/null
+++ b/oidc-common-profile-impl/src/test/java/net/shibboleth/oidc/profile/decoding/impl/HTTPPostAuthnResponseDecoderTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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.decoding.impl;
+
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+import org.opensaml.messaging.decoder.MessageDecodingException;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.nimbusds.openid.connect.sdk.AuthenticationResponse;
+import com.nimbusds.openid.connect.sdk.AuthenticationSuccessResponse;
+
+public class HTTPPostAuthnResponseDecoderTest {
+
+ /** Mock servlet response.*/
+ private MockHttpServletRequest mockRequest;
+
+ /** The encoder to test.*/
+ private HTTPPostAuthnResponseDecoder decoder;
+
+ @BeforeMethod public void setUp() throws Exception {
+ decoder = new HTTPPostAuthnResponseDecoder();
+ mockRequest = new MockHttpServletRequest();
+ }
+
+ @Test
+ public void testSuccessfulDecoding_Query_AuthCode() throws Exception {
+ mockRequest.setMethod("POST");
+ mockRequest.setRequestURI("/idp/profile/Authn/OIDC/RP/callback");
+ mockRequest.addParameter("state", "91c28622815dd9a92ef7c984c74c9e39.65317332");
+ mockRequest.addParameter("code", "XSpej7DkB2WYcF1Gzth5CCHw6Oxf3gxR");
+ mockRequest.setContentType("application/x-www-form-urlencoded");
+ decoder.setHttpServletRequest(mockRequest);
+ decoder.initialize();
+ decoder.decode();
+ assertNotNull(decoder.getMessageContext());
+ assertNotNull(decoder.getMessageContext().getMessage());
+ assertTrue(decoder.getMessageContext().getMessage() instanceof AuthenticationSuccessResponse);
+ assertTrue(((AuthenticationResponse)
+ decoder.getMessageContext().getMessage()).getState()
+ .getValue().equals("91c28622815dd9a92ef7c984c74c9e39.65317332"));
+ assertTrue(((AuthenticationSuccessResponse)
+ decoder.getMessageContext().getMessage()).getAuthorizationCode()
+ .getValue().equals("XSpej7DkB2WYcF1Gzth5CCHw6Oxf3gxR"));
+ }
+
+ @Test(expectedExceptions = MessageDecodingException.class)
+ public void testWrongMethod() throws Exception {
+ mockRequest.setMethod("GET");
+ decoder.setHttpServletRequest(mockRequest);
+ decoder.initialize();
+ decoder.decode();
+ }
+
+
+}
diff --git a/oidc-common-profile-impl/src/test/java/net/shibboleth/oidc/profile/decoding/impl/HTTPRedirectAuthnResponseDecoderTest.java b/oidc-common-profile-impl/src/test/java/net/shibboleth/oidc/profile/decoding/impl/HTTPRedirectAuthnResponseDecoderTest.java
new file mode 100644
index 0000000..49bff29
--- /dev/null
+++ b/oidc-common-profile-impl/src/test/java/net/shibboleth/oidc/profile/decoding/impl/HTTPRedirectAuthnResponseDecoderTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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.decoding.impl;
+
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+import org.opensaml.messaging.decoder.MessageDecodingException;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.nimbusds.openid.connect.sdk.AuthenticationResponse;
+import com.nimbusds.openid.connect.sdk.AuthenticationSuccessResponse;
+
+public class HTTPRedirectAuthnResponseDecoderTest {
+
+ /** Mock servlet response.*/
+ private MockHttpServletRequest mockRequest;
+
+ /** The encoder to test.*/
+ private HTTPRedirectAuthnResponseDecoder decoder;
+
+ @BeforeMethod public void setUp() throws Exception {
+ decoder = new HTTPRedirectAuthnResponseDecoder();
+ mockRequest = new MockHttpServletRequest();
+ }
+
+ @Test
+ public void testSuccessfulDecoding_Query_AuthCode() throws Exception {
+ mockRequest.setMethod("GET");
+ mockRequest.setRequestURI("https://localhost/idp/profile/Authn/OIDC/RP/"
+ + "callback?code=XSpej7DkB2WYcF1Gzth5CCHw6Oxf3gxR&state=91c28622815dd9a92ef7c984c74c9e39.65317332");
+ mockRequest.setQueryString("code=XSpej7DkB2WYcF1Gzth5CCHw6Oxf3gxR&state=91c28622815dd9a92ef7c984c74c9e39.65317332");
+ mockRequest.setContentType("application/x-www-form-urlencoded");
+ decoder.setHttpServletRequest(mockRequest);
+ decoder.initialize();
+ decoder.decode();
+ assertNotNull(decoder.getMessageContext());
+ assertNotNull(decoder.getMessageContext().getMessage());
+ assertTrue(decoder.getMessageContext().getMessage() instanceof AuthenticationSuccessResponse);
+ assertTrue(((AuthenticationResponse)
+ decoder.getMessageContext().getMessage()).getState()
+ .getValue().equals("91c28622815dd9a92ef7c984c74c9e39.65317332"));
+ assertTrue(((AuthenticationSuccessResponse)
+ decoder.getMessageContext().getMessage()).getAuthorizationCode()
+ .getValue().equals("XSpej7DkB2WYcF1Gzth5CCHw6Oxf3gxR"));
+ }
+
+ @Test(expectedExceptions = MessageDecodingException.class)
+ public void testWrongMethod() throws Exception {
+ mockRequest.setMethod("POST");
+ decoder.setHttpServletRequest(mockRequest);
+ decoder.initialize();
+ decoder.decode();
+ }
+
+
+}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list