org.mule.modules.acquialift.client.HmacUtil.java Source code

Java tutorial

Introduction

Here is the source code for org.mule.modules.acquialift.client.HmacUtil.java

Source

/**
 * (c) 2003-2015 MuleSoft, Inc. The software in this package is published under the terms of the CPAL v1.0 license,
 * a copy of which has been included with this distribution in the LICENSE.md file.
 */

package org.mule.modules.acquialift.client;

import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MultivaluedMap;

import org.apache.commons.lang.StringUtils;
import org.mule.util.Base64;

/**
 * HMAC Authentication Helper Util
 */
public class HmacUtil {

    private HmacUtil() {
    }

    private static final String NEW_LINE_SEPERATOR = "\n";
    private static final String HEADER_SEPERATOR = ":";
    private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1";
    private static final String HMAC_AUTHORIZATION_PROVIDER = "HMAC";
    private static final String DEFAULT_USER_AGENT = "Jersey";

    /**
     * Canonicalize Request
     * 
     * @param method
     *            Requested HTTP method
     * @param uri
     *            Requested URI
     * @param headers
     *            Requested HTTP headers
     * 
     * @return the canonical request String.
     */
    public static String canonicalizeRequest(String method, URI uri, final MultivaluedMap<String, Object> headers) {
        List<String> headerWhiteList = new ArrayList<String>();
        headerWhiteList.add(HttpHeaders.ACCEPT);
        headerWhiteList.add(HttpHeaders.HOST);
        headerWhiteList.add(HttpHeaders.USER_AGENT);

        StringBuilder builder = new StringBuilder();
        builder.append(method.toUpperCase());

        builder.append(NEW_LINE_SEPERATOR);

        headers.put(HttpHeaders.USER_AGENT, Collections.singletonList((Object) DEFAULT_USER_AGENT));
        headers.put(HttpHeaders.HOST, Collections.singletonList((Object) uri.getHost()));
        headers.remove(HttpHeaders.AUTHORIZATION);
        Map<String, Object> sortedHeaders = new TreeMap<String, Object>(headers);
        for (Map.Entry<String, Object> entry : sortedHeaders.entrySet()) {
            if (headerWhiteList.contains(entry.getKey())) {
                builder.append(entry.getKey().toLowerCase().trim()).append(HEADER_SEPERATOR);
                List<?> value = (List<?>) entry.getValue();
                if (!value.isEmpty() && value.get(0) != null) {
                    builder.append(value.get(0).toString().trim());
                }
                builder.append(NEW_LINE_SEPERATOR);
            }
        }

        builder.append(uri.getPath());
        String query = uri.getQuery();
        if (StringUtils.isNotBlank(query)) {
            builder.append("?").append(query);
        }
        return builder.toString();
    }

    /**
     * Get Authorization Header
     * 
     * @param method
     *            Requested HTTP method
     * @param uri
     *            Requested URI
     * @param headers
     *            Requested HTTP headers
     * @param accessKey
     *            Access Key to encode the request
     * @param secretKey
     *            Secret Key to encode the request
     * 
     * @return the full generated HMAC HTTP Authorization header
     */
    public static String getAuthHeader(String method, URI uri, final MultivaluedMap<String, Object> headers,
            String accessKey, String secretKey) throws Exception {
        return HMAC_AUTHORIZATION_PROVIDER + " " + accessKey + HEADER_SEPERATOR
                + hmacEncodeRequest(canonicalizeRequest(method, uri, headers), secretKey);
    }

    private static String hmacEncodeRequest(String canonicalRequest, String secretKey) throws Exception {
        SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), HMAC_SHA1_ALGORITHM);
        Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
        mac.init(keySpec);
        byte[] result = mac.doFinal(canonicalRequest.getBytes(StandardCharsets.UTF_8));
        return Base64.encodeBytes(result);
    }

}