org.encuestame.oauth1.support.OAuth1Utils.java Source code

Java tutorial

Introduction

Here is the source code for org.encuestame.oauth1.support.OAuth1Utils.java

Source

/*
 ************************************************************************************
 * Copyright (C) 2001-2011 encuestame: system online surveys Copyright (C) 2011
 * encuestame Development Team.
 * Licensed under the Apache Software License version 2.0
 * 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 org.encuestame.oauth1.support;

import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpRequest;

/**
 * Oauth 1 utils.
 * @author Picado, Juan juanATencuestame.org
 * @since
 */
public class OAuth1Utils {

    /**
     *
     */
    public static final String HMAC_SHA1_SIGNATURE_NAME = "HMAC-SHA1";

    /**
     *
     */
    private static final String HMAC_SHA1_MAC_NAME = "HmacSHA1";

    /**
     * Constructor.
     */
    private OAuth1Utils() {
    }

    /**
     *
     * @param targetUrl
     * @param oauthParameters
     * @param additionalParameters
     * @param method
     * @param consumerSecret
     * @param tokenSecret
     * @return
     */
    public static String buildAuthorizationHeaderValue(String targetUrl, Map<String, String> oauthParameters,
            Map<String, String> additionalParameters, HttpMethod method, String consumerSecret,
            String tokenSecret) {
        String baseString = buildBaseString(targetUrl, oauthParameters, additionalParameters, method);
        String signature = calculateSignature(baseString, consumerSecret, tokenSecret);
        String header = "OAuth ";
        for (String key : oauthParameters.keySet()) {
            header += key + "=\"" + encode(oauthParameters.get(key)) + "\", ";
        }
        header += "oauth_signature=\"" + encode(signature) + "\"";
        return header;
    }

    /**
     *
     * @param consumerKey
     * @return
     */
    public static Map<String, String> commonOAuthParameters(String consumerKey) {
        Map<String, String> oauthParameters = new HashMap<String, String>();
        oauthParameters.put("oauth_consumer_key", consumerKey);
        oauthParameters.put("oauth_signature_method", HMAC_SHA1_SIGNATURE_NAME);
        oauthParameters.put("oauth_timestamp", String.valueOf(System.currentTimeMillis() / 1000));
        oauthParameters.put("oauth_nonce", UUID.randomUUID().toString());
        oauthParameters.put("oauth_version", "1.0");
        return oauthParameters;
    }

    /**
     *
     * @param request
     * @param body
     * @param consumerKey
     * @param consumerSecret
     * @param accessToken
     * @param accessTokenSecret
     * @return
     */
    public static String spring30buildAuthorizationHeaderValue(ClientHttpRequest request, byte[] body,
            String consumerKey, String consumerSecret, String accessToken, String accessTokenSecret) {
        Map<String, String> oauthParameters = commonOAuthParameters(consumerKey);
        oauthParameters.put("oauth_token", accessToken);
        Map<String, String> aditionalParameters = extractBodyParameters(request.getHeaders().getContentType(),
                body);
        Map<String, String> queryParameters = extractParameters(request.getURI().getQuery());
        aditionalParameters.putAll(queryParameters);
        String baseRequestUrl = getBaseUrlWithoutPortOrQueryString(request.getURI());
        return OAuth1Utils.buildAuthorizationHeaderValue(baseRequestUrl, oauthParameters, aditionalParameters,
                request.getMethod(), consumerSecret, accessTokenSecret);
    }

    /**
     *
     * @param targetUrl
     * @param parameters
     * @param additionalParameters
     * @param method
     * @return
     */
    private static String buildBaseString(String targetUrl, Map<String, String> parameters,
            Map<String, String> additionalParameters, HttpMethod method) {
        Map<String, String> allParameters = new HashMap<String, String>(parameters);
        allParameters.putAll(additionalParameters);
        String baseString = method.toString() + "&" + encode(targetUrl) + "&";
        List<String> keys = new ArrayList<String>(allParameters.keySet());
        Collections.sort(keys);
        String separator = "";
        for (String key : keys) {
            String parameterValue = allParameters.get(key);
            baseString += encode(separator + key + "=" + encode(parameterValue));
            separator = "&";
        }
        return baseString;
    }

    /**
     *
     * @param baseString
     * @param consumerSecret
     * @param tokenSecret
     * @return
     */
    private static String calculateSignature(String baseString, String consumerSecret, String tokenSecret) {
        String key = consumerSecret + "&" + (tokenSecret == null ? "" : tokenSecret);
        return sign(baseString, key);
    }

    /**
     *
     * @param signatureBaseString
     * @param key
     * @return
     */
    private static String sign(String signatureBaseString, String key) {
        try {
            Mac mac = Mac.getInstance(HMAC_SHA1_MAC_NAME);
            SecretKeySpec spec = new SecretKeySpec(key.getBytes(), HMAC_SHA1_MAC_NAME);
            mac.init(spec);
            byte[] text = signatureBaseString.getBytes("UTF-8");
            byte[] signatureBytes = mac.doFinal(text);
            signatureBytes = Base64.encodeBase64(signatureBytes);
            String signature = new String(signatureBytes, "UTF-8");
            return signature;
        } catch (NoSuchAlgorithmException e) {
            throw new IllegalStateException(e);
        } catch (InvalidKeyException e) {
            throw new IllegalStateException(e);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     *
     * @param bodyType
     * @param bodyBytes
     * @return
     */
    private static Map<String, String> extractBodyParameters(MediaType bodyType, byte[] bodyBytes) {
        if (bodyType != null && bodyType.equals(MediaType.APPLICATION_FORM_URLENCODED)) {
            return extractParameters(new String(bodyBytes));
        }
        return new HashMap<String, String>();
    }

    /**
     *
     * @param parameterString
     * @return
     */
    private static Map<String, String> extractParameters(String parameterString) {
        Map<String, String> params = new HashMap<String, String>();
        if (parameterString != null) {
            String[] paramPairs = parameterString.split("&");
            for (String pair : paramPairs) {
                String[] keyValue = pair.split("=");
                if (keyValue.length == 2) {
                    // TODO: Determine if this decode step is necessary, since it's just going to be encoded again later
                    params.put(keyValue[0], decode(keyValue[1]));
                }
            }
        }
        return params;
    }

    /**
     *
     * @param uri
     * @return
     */
    private static String getBaseUrlWithoutPortOrQueryString(URI uri) {
        String baseRequestUrl = uri.toString().replaceAll("\\?.*", "").replace("\\:\\d{4}", "");
        return baseRequestUrl;
    }

    /**
     *
     * @param in
     * @return
     */
    private static String encode(String in) {
        try {
            // See http://oauth.net/core/1.0a/#encoding_parameters
            return URLEncoder.encode(in, "UTF-8").replace("+", "%20").replace("*", "%2A").replace("%7E", "~");
        } catch (Exception wontHappen) {
            return null;
        }
    }

    /**
     *
     * @param encoded
     * @return
     */
    private static String decode(String encoded) {
        try {
            return URLDecoder.decode(encoded, "UTF-8");
        } catch (UnsupportedEncodingException shouldntHappen) {
            return encoded;
        }
    }
}