All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.api.client.auth.oauth.OAuthParameters Maven / Gradle / Ivy

Go to download

Google OAuth Client Library for Java. Functionality that works on all supported Java platforms, including Java 5 (or higher) desktop (SE) and web (EE), Android, and Google App Engine.

The newest version!
/*
 * Copyright (c) 2010 Google Inc.
 *
 * 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 com.google.api.client.auth.oauth;

import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpContent;
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;
import java.util.Collection;
import java.util.Map;

/**
 * {@link Beta} 
* OAuth 1.0a parameter manager. * *

The only required non-computed fields are {@link #signer} and {@link #consumerKey}. Use {@link * #token} to specify token or temporary credentials. * *

Sample usage, taking advantage that this class implements {@link HttpRequestInitializer}: * *

 * public static HttpRequestFactory createRequestFactory(HttpTransport transport) {
 * OAuthParameters parameters = new OAuthParameters();
 * // ...
 * return transport.createRequestFactory(parameters);
 * }
 * 
* *

If you have a custom request initializer, take a look at the sample usage for {@link * HttpExecuteInterceptor}, which this class also implements. * * @since 1.0 * @author Yaniv Inbar */ @Beta public final class OAuthParameters implements HttpExecuteInterceptor, HttpRequestInitializer { /** Secure random number generator to sign requests. */ private static final SecureRandom RANDOM = new SecureRandom(); /** Required OAuth signature algorithm. */ public OAuthSigner signer; /** * Absolute URI back to which the server will redirect the resource owner when the Resource Owner * Authorization step is completed. */ public String callback; /** Required identifier portion of the client credentials (equivalent to a username). */ public String consumerKey; /** Required nonce value. Should be computed using {@link #computeNonce()}. */ public String nonce; /** Realm. */ public String realm; /** Signature. Required but normally computed using {@link #computeSignature}. */ public String signature; /** * Name of the signature method used by the client to sign the request. Required, but normally * computed using {@link #computeSignature}. */ public String signatureMethod; /** Required timestamp value. Should be computed using {@link #computeTimestamp()}. */ public String timestamp; /** * Token value used to associate the request with the resource owner or {@code null} if the * request is not associated with a resource owner. */ public String token; /** The verification code received from the server. */ public String verifier; /** * Must either be "1.0" or {@code null} to skip. Provides the version of the authentication * process as defined in this specification. */ public String version; private static final PercentEscaper ESCAPER = new PercentEscaper("-_.~"); /** * Computes a nonce based on the hex string of a random non-negative long, setting the value of * the {@link #nonce} field. */ public void computeNonce() { nonce = Long.toHexString(Math.abs(RANDOM.nextLong())); } /** * Computes a timestamp based on the current system time, setting the value of the {@link * #timestamp} field. */ public void computeTimestamp() { timestamp = Long.toString(System.currentTimeMillis() / 1000); } /** * This class is used as the Entry for the SortedMultiset. Parameters are sorted lexically first * by key, then by value. */ private static class Parameter implements Comparable { private final String key; private final String value; public Parameter(String key, String value) { this.key = key; this.value = value; } public String getKey() { return key; } public String getValue() { return value; } @Override public int compareTo(Parameter p) { // Compare lexically by key, then value on ties int result = key.compareTo(p.key); return result == 0 ? value.compareTo(p.value) : result; } } /** * Computes a new signature based on the fields and the given request method and URL, setting the * values of the {@link #signature} and {@link #signatureMethod} fields. * * @throws GeneralSecurityException general security exception */ public void computeSignature(String requestMethod, GenericUrl requestUrl) throws GeneralSecurityException { OAuthSigner signer = this.signer; String signatureMethod = this.signatureMethod = signer.getSignatureMethod(); // oauth_* parameters (except oauth_signature) SortedMultiset parameters = TreeMultiset.create(); putParameterIfValueNotNull(parameters, "oauth_callback", callback); putParameterIfValueNotNull(parameters, "oauth_consumer_key", consumerKey); putParameterIfValueNotNull(parameters, "oauth_nonce", nonce); putParameterIfValueNotNull(parameters, "oauth_signature_method", signatureMethod); putParameterIfValueNotNull(parameters, "oauth_timestamp", timestamp); putParameterIfValueNotNull(parameters, "oauth_token", token); putParameterIfValueNotNull(parameters, "oauth_verifier", verifier); putParameterIfValueNotNull(parameters, "oauth_version", version); // parse request URL for query parameters for (Map.Entry fieldEntry : requestUrl.entrySet()) { Object value = fieldEntry.getValue(); if (value != null) { String name = fieldEntry.getKey(); if (value instanceof Collection) { for (Object repeatedValue : (Collection) value) { putParameter(parameters, name, repeatedValue); } } else { putParameter(parameters, name, value); } } } // normalize parameters StringBuilder parametersBuf = new StringBuilder(); boolean first = true; for (Parameter parameter : parameters.elementSet()) { if (first) { first = false; } else { parametersBuf.append('&'); } parametersBuf.append(parameter.getKey()); String value = parameter.getValue(); if (value != null) { parametersBuf.append('=').append(value); } } String normalizedParameters = parametersBuf.toString(); // normalize URL, removing any query parameters and possibly port GenericUrl normalized = new GenericUrl(); String scheme = requestUrl.getScheme(); normalized.setScheme(scheme); normalized.setHost(requestUrl.getHost()); normalized.setPathParts(requestUrl.getPathParts()); int port = requestUrl.getPort(); if ("http".equals(scheme) && port == 80 || "https".equals(scheme) && port == 443) { port = -1; } normalized.setPort(port); String normalizedPath = normalized.build(); // signature base string StringBuilder buf = new StringBuilder(); buf.append(escape(requestMethod)).append('&'); buf.append(escape(normalizedPath)).append('&'); buf.append(escape(normalizedParameters)); String signatureBaseString = buf.toString(); signature = signer.computeSignature(signatureBaseString); } /** * Returns the {@code Authorization} header value to use with the OAuth parameter values found in * the fields. */ public String getAuthorizationHeader() { StringBuilder buf = new StringBuilder("OAuth"); appendParameter(buf, "realm", realm); appendParameter(buf, "oauth_callback", callback); appendParameter(buf, "oauth_consumer_key", consumerKey); appendParameter(buf, "oauth_nonce", nonce); appendParameter(buf, "oauth_signature", signature); appendParameter(buf, "oauth_signature_method", signatureMethod); appendParameter(buf, "oauth_timestamp", timestamp); appendParameter(buf, "oauth_token", token); appendParameter(buf, "oauth_verifier", verifier); appendParameter(buf, "oauth_version", version); // hack: we have to remove the extra ',' at the end return buf.substring(0, buf.length() - 1); } private void appendParameter(StringBuilder buf, String name, String value) { if (value != null) { buf.append(' ').append(escape(name)).append("=\"").append(escape(value)).append("\","); } } private void putParameterIfValueNotNull( Multiset parameters, String key, String value) { if (value != null) { putParameter(parameters, key, value); } } private void putParameter(Multiset parameters, String key, Object value) { parameters.add(new Parameter(escape(key), value == null ? null : escape(value.toString()))); } /** Returns the escaped form of the given value using OAuth escaping rules. */ public static String escape(String value) { return ESCAPER.escape(value); } public void initialize(HttpRequest request) throws IOException { request.setInterceptor(this); } public void intercept(HttpRequest request) throws IOException { computeNonce(); computeTimestamp(); try { 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); if (urlEncodedParams != null) { for (Map.Entry entry : urlEncodedParams.entrySet()) { url.remove(entry.getKey()); } } } catch (GeneralSecurityException e) { IOException io = new IOException(); io.initCause(e); throw io; } request.getHeaders().setAuthorization(getAuthorizationHeader()); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy