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

com.microsoft.azure.storage.core.StorageCredentialsHelper Maven / Gradle / Ivy

/**
 * Copyright Microsoft Corporation
 * 
 * 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.microsoft.azure.storage.core;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;

import com.microsoft.azure.storage.*;

import javax.net.ssl.HttpsURLConnection;

/**
 * RESERVED FOR INTERNAL USE. A helper method for StorageCredentials.
 */
public final class StorageCredentialsHelper {

    /**
     *  RESERVED, for internal use only. Gets a value indicating whether a
     *  request can be signed under the Shared Key authentication scheme using
     *  the specified credentials.
    
     *  @return true if a request can be signed with these
     *  credentials; otherwise, false
     */
    public static boolean canCredentialsSignRequest(final StorageCredentials creds) {
        return creds.getClass().equals(StorageCredentialsAccountAndKey.class);
    }

    /**
     *  RESERVED, for internal use only. Gets a value indicating whether a
     *  client can be generated under the Shared Key or Shared Access Signature
     *  authentication schemes using the specified credentials.
     *  @return true if a client can be generated with these
     *  credentials; otherwise, false
     */
    public static boolean canCredentialsGenerateClient(final StorageCredentials creds) {
        return canCredentialsSignRequest(creds) || creds.getClass().equals(StorageCredentialsSharedAccessSignature.class) ||
                creds.getClass().equals(StorageCredentialsToken.class);
    }

    /**
     * Computes a signature for the specified string using the HMAC-SHA256 algorithm.
     * 
     * @param value
     *            The UTF-8-encoded string to sign.
     * 
     * @return A String that contains the HMAC-SHA256-encoded signature.
     * 
     * @throws InvalidKeyException
     *             If the key is not a valid Base64-encoded string.
     */
    public static synchronized String computeHmac256(final StorageCredentials creds, final String value) throws InvalidKeyException {
        if (creds.getClass().equals(StorageCredentialsAccountAndKey.class)) {
            byte[] utf8Bytes = null;
            try {
                utf8Bytes = value.getBytes(Constants.UTF8_CHARSET);
            }
            catch (final UnsupportedEncodingException e) {
                throw new IllegalArgumentException(e);
            }
            return Base64.encode(((StorageCredentialsAccountAndKey) creds).getHmac256().doFinal(utf8Bytes));
        }
        else {
            return null;
        }
    }

    /**
     * Signs a request using the specified operation context under either the Shared Key or Token authentication scheme.
     * 
     * @param request
     *            An HttpURLConnection object that represents the request to sign.
     * @param contentLength
     *            The length of the content written to the output stream. If unknown, specify -1.
     * @param opContext
     *            An {@link OperationContext} object that represents the context for the current operation. This object
     *            is used to track requests to the storage service, and to provide additional runtime information about
     *            the operation.
     * 
     * @throws InvalidKeyException
     *             If the given key is invalid.
     * @throws StorageException
     *             If a storage service error occurred.
     */
    public static void signBlobQueueAndFileRequest(final StorageCredentials creds,
            final java.net.HttpURLConnection request, final long contentLength, OperationContext opContext)
            throws InvalidKeyException, StorageException {
        
        if (creds.getClass().equals(StorageCredentialsAccountAndKey.class)) {
            opContext = opContext == null ? new OperationContext() : opContext;
            request.setRequestProperty(Constants.HeaderConstants.DATE, Utility.getGMTTime());
            final Canonicalizer canonicalizer = CanonicalizerFactory.getBlobQueueFileCanonicalizer(request);

            final String stringToSign = canonicalizer.canonicalize(request, creds.getAccountName(), contentLength);

            final String computedBase64Signature = StorageCredentialsHelper.computeHmac256(creds, stringToSign);

            Logger.trace(opContext, LogConstants.SIGNING, stringToSign);
            
            request.setRequestProperty(Constants.HeaderConstants.AUTHORIZATION,
                    String.format("%s %s:%s", "SharedKey", creds.getAccountName(), computedBase64Signature));
        } else if (creds.getClass().equals(StorageCredentialsToken.class)) {
            // the token is set as a header to authenticate the HTTPS requests
            if (request instanceof HttpsURLConnection) {
                request.setRequestProperty(Constants.HeaderConstants.AUTHORIZATION,
                        String.format("%s %s", Constants.HeaderConstants.BEARER, ((StorageCredentialsToken)creds).getToken()));
            }
            else {
                throw new IllegalArgumentException("Token credential is only supported for HTTPS requests.");
            }
        }
    }
    
    /**
     * Signs a request using the specified operation context under the Shared Key authentication scheme.
     * 
     * @param request
     *            An HttpURLConnection object that represents the request to sign.
     * @param contentLength
     *            The length of the content written to the output stream. If unknown, specify -1.
     * @param opContext
     *            An {@link OperationContext} object that represents the context for the current operation. This object
     *            is used to track requests to the storage service, and to provide additional runtime information about
     *            the operation.
     * 
     * @throws InvalidKeyException
     *             If the given key is invalid.
     * @throws StorageException
     *             If a storage service error occurred.
     */
    public static void signTableRequest(final StorageCredentials creds, final java.net.HttpURLConnection request,
            final long contentLength, OperationContext opContext) throws InvalidKeyException, StorageException {
        if (creds.getClass().equals(StorageCredentialsAccountAndKey.class)) {
            opContext = opContext == null ? new OperationContext() : opContext;
            request.setRequestProperty(Constants.HeaderConstants.DATE, Utility.getGMTTime());

            final Canonicalizer canonicalizer = CanonicalizerFactory.getTableCanonicalizer(request);

            final String stringToSign = canonicalizer.canonicalize(request, creds.getAccountName(), contentLength);

            final String computedBase64Signature = StorageCredentialsHelper.computeHmac256(creds, stringToSign);
            
            Logger.trace(opContext, LogConstants.SIGNING, stringToSign);

            request.setRequestProperty(Constants.HeaderConstants.AUTHORIZATION,
                    String.format("%s %s:%s", "SharedKey", creds.getAccountName(), computedBase64Signature));
        }
    }
    
    /**
     * A private default constructor. All methods of this class are static so no instances of it should ever be created.
     */
    private StorageCredentialsHelper() {
        //No op
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy