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

com.microsoft.azure.storage.blob.ServiceSASSignatureValues Maven / Gradle / Ivy

There is a newer version: 11.0.1
Show newest version
/*
 * 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.blob;

import java.security.InvalidKeyException;
import java.time.OffsetDateTime;

/**
 * ServiceSASSignatureValues is used to generate a Shared Access Signature (SAS) for an Azure Storage service. Once
 * all the values here are set appropriately, call generateSASQueryParameters to obtain a representation of the SAS
 * which can actually be applied to blob urls. Note: that both this class and {@link SASQueryParameters} exist because
 * the former is mutable and a logical representation while the latter is immutable and used to generate actual REST
 * requests.
 * 

* Please see here * for more conceptual information on SAS. *

* Please see here for * more details on each value, including which are required. * * @apiNote ## Sample Code \n * [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=service_sas "Sample code for ServiceSASSignatureValues")] \n * For more samples, please see the [Samples file](%https://github.com/Azure/azure-storage-java/blob/master/src/test/java/com/microsoft/azure/storage/Samples.java) */ public final class ServiceSASSignatureValues { private String version = Constants.HeaderConstants.TARGET_STORAGE_VERSION; private SASProtocol protocol; private OffsetDateTime startTime; private OffsetDateTime expiryTime; private String permissions; private IPRange ipRange; private String containerName; private String blobName; private String identifier; private String cacheControl; private String contentDisposition; private String contentEncoding; private String contentLanguage; private String contentType; /** * Creates an object with empty values for all fields. */ public ServiceSASSignatureValues() { } /** * The version of the service this SAS will target. If not specified, it will default to the version targeted by the * library. */ public String version() { return version; } /** * The version of the service this SAS will target. If not specified, it will default to the version targeted by the * library. */ public ServiceSASSignatureValues withVersion(String version) { this.version = version; return this; } /** * {@link SASProtocol} */ public SASProtocol protocol() { return protocol; } /** * {@link SASProtocol} */ public ServiceSASSignatureValues withProtocol(SASProtocol protocol) { this.protocol = protocol; return this; } /** * When the SAS will take effect. */ public OffsetDateTime startTime() { return startTime; } /** * When the SAS will take effect. */ public ServiceSASSignatureValues withStartTime(OffsetDateTime startTime) { this.startTime = startTime; return this; } /** * The time after which the SAS will no longer work. */ public OffsetDateTime expiryTime() { return expiryTime; } /** * The time after which the SAS will no longer work. */ public ServiceSASSignatureValues withExpiryTime(OffsetDateTime expiryTime) { this.expiryTime = expiryTime; return this; } /** * Please refer to either {@link ContainerSASPermission} or {@link BlobSASPermission} depending on the resource * being accessed for help constructing the permissions string. */ public String permissions() { return permissions; } /** * Please refer to either {@link ContainerSASPermission} or {@link BlobSASPermission} depending on the resource * being accessed for help constructing the permissions string. */ public ServiceSASSignatureValues withPermissions(String permissions) { this.permissions = permissions; return this; } /** * {@link IPRange} */ public IPRange ipRange() { return ipRange; } /** * {@link IPRange} */ public ServiceSASSignatureValues withIpRange(IPRange ipRange) { this.ipRange = ipRange; return this; } /** * The name of the container the SAS user may access. */ public String containerName() { return containerName; } /** * The name of the container the SAS user may access. */ public ServiceSASSignatureValues withContainerName(String containerName) { this.containerName = containerName; return this; } /** * The name of the container the SAS user may access. */ public String blobName() { return blobName; } /** * The name of the container the SAS user may access. */ public ServiceSASSignatureValues withBlobName(String blobName) { this.blobName = blobName; return this; } /** * The name of the access policy on the container this SAS references if any. Please see * here * for more information. */ public String identifier() { return identifier; } /** * The name of the access policy on the container this SAS references if any. Please see * here * for more information. */ public ServiceSASSignatureValues withIdentifier(String identifier) { this.identifier = identifier; return this; } /** * The cache-control header for the SAS. */ public String cacheControl() { return cacheControl; } /** * The cache-control header for the SAS. */ public ServiceSASSignatureValues withCacheControl(String cacheControl) { this.cacheControl = cacheControl; return this; } /** * The content-disposition header for the SAS. */ public String contentDisposition() { return contentDisposition; } /** * The content-disposition header for the SAS. */ public ServiceSASSignatureValues withContentDisposition(String contentDisposition) { this.contentDisposition = contentDisposition; return this; } /** * The content-encoding header for the SAS. */ public String contentEncoding() { return contentEncoding; } /** * The content-encoding header for the SAS. */ public ServiceSASSignatureValues withContentEncoding(String contentEncoding) { this.contentEncoding = contentEncoding; return this; } /** * The content-language header for the SAS. */ public String contentLanguage() { return contentLanguage; } /** * The content-language header for the SAS. */ public ServiceSASSignatureValues withContentLanguage(String contentLanguage) { this.contentLanguage = contentLanguage; return this; } /** * The content-type header for the SAS. */ public String contentType() { return contentType; } /** * The content-type header for the SAS. */ public ServiceSASSignatureValues withContentType(String contentType) { this.contentType = contentType; return this; } /** * Uses an account's shared key credential to sign these signature values to produce the proper SAS query * parameters. * * @param sharedKeyCredentials * A {@link SharedKeyCredentials} object used to sign the SAS values. * * @return {@link SASQueryParameters} */ public SASQueryParameters generateSASQueryParameters(SharedKeyCredentials sharedKeyCredentials) { Utility.assertNotNull("sharedKeyCredentials", sharedKeyCredentials); Utility.assertNotNull("version", this.version); Utility.assertNotNull("containerName", this.containerName); String resource = "c"; String verifiedPermissions = null; // Calling parse and toString guarantees the proper ordering and throws on invalid characters. if (Utility.isNullOrEmpty(this.blobName)) { if (this.permissions != null) { verifiedPermissions = ContainerSASPermission.parse(this.permissions).toString(); } } else { if (this.permissions != null) { verifiedPermissions = BlobSASPermission.parse(this.permissions).toString(); } resource = "b"; } // Signature is generated on the un-url-encoded values. final String stringToSign = stringToSign(verifiedPermissions, sharedKeyCredentials); String signature = null; try { signature = sharedKeyCredentials.computeHmac256(stringToSign); } catch (InvalidKeyException e) { throw new Error(e); // The key should have been validated by now. If it is no longer valid here, we fail. } return new SASQueryParameters(this.version, null, null, this.protocol, this.startTime, this.expiryTime, this.ipRange, this.identifier, resource, this.permissions, signature, this.cacheControl, this.contentDisposition, this.contentEncoding, this.contentLanguage, this.contentType); } private String getCanonicalName(String accountName) { // Container: "/blob/account/containername" // Blob: "/blob/account/containername/blobname" StringBuilder canonicalName = new StringBuilder("/blob"); canonicalName.append('/').append(accountName).append('/').append(this.containerName); if (!Utility.isNullOrEmpty(this.blobName)) { canonicalName.append("/").append(this.blobName); } return canonicalName.toString(); } private String stringToSign(final String verifiedPermissions, final SharedKeyCredentials sharedKeyCredentials) { return String.join("\n", verifiedPermissions == null ? "" : verifiedPermissions, this.startTime == null ? "" : Utility.ISO8601UTCDateFormatter.format(this.startTime), this.expiryTime == null ? "" : Utility.ISO8601UTCDateFormatter.format(this.expiryTime), getCanonicalName(sharedKeyCredentials.getAccountName()), this.identifier == null ? "" : this.identifier, this.ipRange == null ? IPRange.DEFAULT.toString() : this.ipRange.toString(), this.protocol == null ? "" : protocol.toString(), this.version, this.cacheControl == null ? "" : this.cacheControl, this.contentDisposition == null ? "" : this.contentDisposition, this.contentEncoding == null ? "" : this.contentEncoding, this.contentLanguage == null ? "" : this.contentLanguage, this.contentType == null ? "" : this.contentType ); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy