Skip to content

Commit

Permalink
fix: oauth1 signing for url encoded content (#538)
Browse files Browse the repository at this point in the history
* 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.

* Changes to support java 1.7.  Also added new test code.

* style: expanded the wild card imports.
  • Loading branch information
cmunden committed Feb 2, 2021
1 parent bf7530b commit d9507e4
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 2 deletions.
Expand Up @@ -14,15 +14,19 @@

package com.google.api.client.auth.oauth;

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;
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;
Expand Down Expand Up @@ -53,7 +57,8 @@
* @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();
Expand Down Expand Up @@ -271,7 +276,19 @@ public void intercept(HttpRequest request) throws IOException {
computeNonce();
computeTimestamp();
try {
computeSignature(request.getRequestMethod(), request.getUrl());
GenericUrl url = request.getUrl();
HttpContent content = request.getContent();
Map<String, Object> urlEncodedParams = null;
if (content instanceof UrlEncodedContent) {
urlEncodedParams = Data.mapOf(((UrlEncodedContent) content).getData());
url.putAll(urlEncodedParams);
}
computeSignature(request.getRequestMethod(), url);
if (urlEncodedParams != null) {
for (Map.Entry<String, Object> entry : urlEncodedParams.entrySet()) {
url.remove(entry.getKey());
}
}
} catch (GeneralSecurityException e) {
IOException io = new IOException();
io.initCause(e);
Expand Down
Expand Up @@ -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;

/**
Expand Down Expand Up @@ -75,6 +83,22 @@ public void testSignature() throws GeneralSecurityException {
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<String, Object> 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();
Expand Down

0 comments on commit d9507e4

Please sign in to comment.