From d0ec683691c2c53742d09c2d4303428140cd67b8 Mon Sep 17 00:00:00 2001 From: Clint Munden Date: Wed, 7 Oct 2020 12:33:45 -0230 Subject: [PATCH 1/3] Fixed OAuth 1.0 signing for requests with URL Encoded Content (typical of POST and PUT HTTP methods) A simple change the the OAuthParameters intercept method that checks if the request has UrlEncodedContent. If it does, then its content is added to the GenericUrl so that the signature can be computed correctly. After the call to computeSignature, the content parameters are removed from the GenericUrl to leave it in its original form. As per the OAuth 1.0 spec here (https://tools.ietf.org/html/rfc5849#page-28), any form encoded request body with a Content-Type of "application/x-www-form-urlencoded" must be included when the request signature is created. --- .../google/api/client/auth/oauth/OAuthParameters.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/google-oauth-client/src/main/java/com/google/api/client/auth/oauth/OAuthParameters.java b/google-oauth-client/src/main/java/com/google/api/client/auth/oauth/OAuthParameters.java index a65925f46..d780661b3 100644 --- a/google-oauth-client/src/main/java/com/google/api/client/auth/oauth/OAuthParameters.java +++ b/google-oauth-client/src/main/java/com/google/api/client/auth/oauth/OAuthParameters.java @@ -280,7 +280,16 @@ public void intercept(HttpRequest request) throws IOException { computeNonce(); computeTimestamp(); try { - computeSignature(request.getRequestMethod(), request.getUrl()); + GenericUrl url = request.getUrl(); + HttpContent content = request.getContent(); + Map urlEncodedParams = null; + if (content instanceof UrlEncodedContent) { + urlEncodedParams = Data.mapOf(((UrlEncodedContent) content).getData()); + url.putAll(urlEncodedParams); + } + computeSignature(request.getRequestMethod(), url); + ofNullable(urlEncodedParams) + .ifPresent(contentParams -> contentParams.forEach((key, value) -> url.remove(key))); } catch (GeneralSecurityException e) { IOException io = new IOException(); io.initCause(e); From 87662e10e2747508e8902e701610f86b597a751b Mon Sep 17 00:00:00 2001 From: "clint.munden" Date: Wed, 7 Oct 2020 13:32:57 -0230 Subject: [PATCH 2/3] Changes to support java 1.7. Also added new test code. --- .../client/auth/oauth/OAuthParameters.java | 19 ++++++++------- .../auth/oauth/OAuthParametersTest.java | 24 +++++++++++++++++++ 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/google-oauth-client/src/main/java/com/google/api/client/auth/oauth/OAuthParameters.java b/google-oauth-client/src/main/java/com/google/api/client/auth/oauth/OAuthParameters.java index d780661b3..a8a48d7fe 100644 --- a/google-oauth-client/src/main/java/com/google/api/client/auth/oauth/OAuthParameters.java +++ b/google-oauth-client/src/main/java/com/google/api/client/auth/oauth/OAuthParameters.java @@ -14,16 +14,14 @@ package com.google.api.client.auth.oauth; -import com.google.api.client.http.GenericUrl; -import com.google.api.client.http.HttpExecuteInterceptor; -import com.google.api.client.http.HttpRequest; -import com.google.api.client.http.HttpRequestInitializer; +import com.google.api.client.http.*; import com.google.api.client.util.Beta; +import com.google.api.client.util.Data; import com.google.api.client.util.escape.PercentEscaper; - import com.google.common.collect.Multiset; import com.google.common.collect.SortedMultiset; import com.google.common.collect.TreeMultiset; + import java.io.IOException; import java.security.GeneralSecurityException; import java.security.SecureRandom; @@ -284,12 +282,15 @@ public void intercept(HttpRequest request) throws IOException { HttpContent content = request.getContent(); Map urlEncodedParams = null; if (content instanceof UrlEncodedContent) { - urlEncodedParams = Data.mapOf(((UrlEncodedContent) content).getData()); - url.putAll(urlEncodedParams); + urlEncodedParams = Data.mapOf(((UrlEncodedContent) content).getData()); + url.putAll(urlEncodedParams); } computeSignature(request.getRequestMethod(), url); - ofNullable(urlEncodedParams) - .ifPresent(contentParams -> contentParams.forEach((key, value) -> url.remove(key))); + if (urlEncodedParams != null) { + for (Map.Entry entry : urlEncodedParams.entrySet()) { + url.remove(entry.getKey()); + } + } } catch (GeneralSecurityException e) { IOException io = new IOException(); io.initCause(e); diff --git a/google-oauth-client/src/test/java/com/google/api/client/auth/oauth/OAuthParametersTest.java b/google-oauth-client/src/test/java/com/google/api/client/auth/oauth/OAuthParametersTest.java index 70791709a..743b43719 100644 --- a/google-oauth-client/src/test/java/com/google/api/client/auth/oauth/OAuthParametersTest.java +++ b/google-oauth-client/src/test/java/com/google/api/client/auth/oauth/OAuthParametersTest.java @@ -15,7 +15,15 @@ package com.google.api.client.auth.oauth; import com.google.api.client.http.GenericUrl; + +import java.io.IOException; import java.security.GeneralSecurityException; +import java.util.Collections; +import java.util.Map; + +import com.google.api.client.http.HttpRequest; +import com.google.api.client.http.UrlEncodedContent; +import com.google.api.client.http.javanet.NetHttpTransport; import junit.framework.TestCase; /** @@ -72,6 +80,22 @@ public void testSignature() throws GeneralSecurityException { assertEquals("GET&https%3A%2F%2Fblue-sea-697d.quartiers047.workers.dev%3A443%2Fhttps%2Fexample.local&foo%3Dbar%26oauth_signature_method%3Dmock", parameters.signature); } + public void testSignatureWithUrlEncodedContent() throws IOException { + OAuthParameters parameters = new OAuthParameters(); + parameters.signer = new MockSigner(); + + GenericUrl url = new GenericUrl("https://example.local?foo=bar"); + Map contentParameters = Collections.singletonMap("this", (Object) "that"); + UrlEncodedContent content = new UrlEncodedContent(contentParameters); + + HttpRequest request = new NetHttpTransport.Builder().build() + .createRequestFactory().buildPostRequest(url, content); + parameters.intercept(request); + + assertTrue(parameters.signature.endsWith("%26this%3Dthat")); + assertEquals("https://example.local?foo=bar", url.build()); + } + public void testSignatureWithRepeatedParameter() throws GeneralSecurityException { OAuthParameters parameters = new OAuthParameters(); parameters.signer = new MockSigner(); From 8d788fd9eb2cb6d33fc8b50f18c84449cce56912 Mon Sep 17 00:00:00 2001 From: "clint.munden" Date: Wed, 7 Oct 2020 17:00:28 -0230 Subject: [PATCH 3/3] style: expanded the wild card imports. --- .../google/api/client/auth/oauth/OAuthParameters.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/google-oauth-client/src/main/java/com/google/api/client/auth/oauth/OAuthParameters.java b/google-oauth-client/src/main/java/com/google/api/client/auth/oauth/OAuthParameters.java index a8a48d7fe..e46923969 100644 --- a/google-oauth-client/src/main/java/com/google/api/client/auth/oauth/OAuthParameters.java +++ b/google-oauth-client/src/main/java/com/google/api/client/auth/oauth/OAuthParameters.java @@ -14,7 +14,12 @@ package com.google.api.client.auth.oauth; -import com.google.api.client.http.*; +import com.google.api.client.http.HttpContent; +import com.google.api.client.http.GenericUrl; +import com.google.api.client.http.HttpExecuteInterceptor; +import com.google.api.client.http.HttpRequest; +import com.google.api.client.http.HttpRequestInitializer; +import com.google.api.client.http.UrlEncodedContent; import com.google.api.client.util.Beta; import com.google.api.client.util.Data; import com.google.api.client.util.escape.PercentEscaper; @@ -56,7 +61,8 @@ public static HttpRequestFactory createRequestFactory(HttpTransport transport) { * @author Yaniv Inbar */ @Beta -public final class OAuthParameters implements HttpExecuteInterceptor, HttpRequestInitializer { +public final class OAuthParameters implements HttpExecuteInterceptor, HttpRequestInitializer +{ /** Secure random number generator to sign requests. */ private static final SecureRandom RANDOM = new SecureRandom();