简体   繁体   English

Azure使用共享访问签名进行Blob存储

[英]Azure Using shared access signatures for blob storage

I'm trying to implement shared access signatures when saving blobs (pdf files) to azure blob storage. 将blob(pdf文件)保存到天蓝色的blob存储时,我正在尝试实现共享访问签名。 I want the link to the pdf file to expire after a set time, but it doesn't seem to be working. 我希望到pdf文件的链接在设置的时间后过期,但似乎无法正常工作。

The pdf creation and save process works fine, I create a pdf file and upload it to azure blob storage. pdf的创建和保存过程运行良好,我创建了一个pdf文件并将其上传到Azure Blob存储。 I can retrieve the blob URL and if I paste it into a browser, the pdf report shows up ok. 我可以检索Blob网址,如果将其粘贴到浏览器中,则pdf报告显示正常。 It never expires though. 它永远不会过期。

I set the expiry time to 2 minutes while Im testing (it would be around 24 hours in production). 我在进行Im测试时将到期时间设置为2分钟(在生产中大约需要24小时)。 I can continue to view the report, nothing stops me. 我可以继续查看报告,没有阻止我的事情。

I am new to shared signature access, but from what I've found so far, it is supposed to stop access after the specified time(is this correct?). 我是共享签名访问的新手,但是从到目前为止发现的情况来看,应该在指定的时间后停止访问(这对吗?)。

This is how I create the storage details (in the constructor of my class): 这是我创建存储详细信息的方式(在我的类的构造函数中):

public BlobService()
{
    //use for local development testing
    _connectionString = Settings.AzureWebJobsStorage;
    this._container = Settings.ReportBlobContainer;

    try
    {
        storageAccount = CloudStorageAccount.Parse(_connectionString);
    }
    catch (StorageException e)
    {
        throw;
    }

    // Get an account SAS token.
    string sasToken = GetAccountSASToken();

    // Use the account SAS token to create authentication credentials.
    StorageCredentials accountSAS = new StorageCredentials(sasToken);

    var blobClient = storageAccount.CreateCloudBlobClient();

    chpBlobContainer = blobClient.GetContainerReference(this._container);
    // Get the URI for the container.
    Uri containerUri = GetContainerUri();
    chpBlobContainer = new CloudBlobContainer(containerUri, accountSAS);

    try
    {
        if (chpBlobContainer.CreateIfNotExists())
        {
            //leave the access to private only (default)
            // Enable public access on the newly created container.
            //chpBlobContainer.SetPermissions(
            //    new BlobContainerPermissions
            //    {
            //        PublicAccess = BlobContainerPublicAccessType.Blob
            //    });
        }
    }
    catch(Exception ex)
    {
        var tmp = ex.Message;
    }

}

and this is how I generate the SAS token 这就是我生成SAS令牌的方式

private string GetAccountSASToken()
{
    // Retrieve storage account information from connection string
    //CloudStorageAccount storageAccount = Common.CreateStorageAccountFromConnectionString();

    // Create a new access policy for the account with the following properties:
    // Permissions: Read, Write, List, Create, Delete
    // ResourceType: Container
    // Expires in 24 hours
    // Protocols: HTTPS or HTTP (note that the storage emulator does not support HTTPS)
    SharedAccessAccountPolicy policy = new SharedAccessAccountPolicy()
    {
        // When the start time for the SAS is omitted, the start time is assumed to be the time when the storage service receives the request. 
        // Omitting the start time for a SAS that is effective immediately helps to avoid clock skew.
        //Permissions = SharedAccessAccountPermissions.Read | SharedAccessAccountPermissions.Write | SharedAccessAccountPermissions.List | SharedAccessAccountPermissions.Create | SharedAccessAccountPermissions.Delete,
        Permissions = SharedAccessAccountPermissions.Read | SharedAccessAccountPermissions.Write | SharedAccessAccountPermissions.Create,
        Services = SharedAccessAccountServices.Blob,
        ResourceTypes = SharedAccessAccountResourceTypes.Container | SharedAccessAccountResourceTypes.Object,
        //SharedAccessExpiryTime = DateTime.UtcNow.AddHours(24),
        //just for testing the expiry works
        SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(2),
        Protocols = SharedAccessProtocol.HttpsOrHttp
    };

    // Create new storage credentials using the SAS token.
    string sasToken = storageAccount.GetSharedAccessSignature(policy);

    // Return the SASToken
    return sasToken;
}

I can see the blob from the Azure storage explorer, so the connection and generation process is fine, its just the expiry. 我可以从Azure存储资源管理器中看到该blob,因此连接和生成过程都很好,只是到期了。

Can anyone help me out? 谁能帮我吗? I am clearly doing something wrong here. 我显然在这里做错了。

As Gaurav Mantri mentioned that it seems that your container is not private. 正如Gaurav Mantri提到的那样,您的容器似乎不是私有的。 There are 3 types of permissions for a container: public,blob,private. 容器有3种权限:public,blob,private。 We could get more info from Set Container ACL . 我们可以从Set Container ACL获取更多信息。

The permissions indicate whether blobs in a container may be accessed publicly. 权限指示是否可以公开访问容器中的Blob。 Beginning with the 2009-09-19 version, the container permissions provide the following options for managing container access: 从2009-09-19版本开始,容器权限提供以下用于管理容器访问的选项:

Full public read access : Container and blob data can be read via anonymous request. 完全公共读取权限 :可以通过匿名请求读取容器和Blob数据。 Clients can enumerate blobs within the container via anonymous request, but cannot enumerate containers within the storage account. 客户端可以通过匿名请求枚举容器中的blob,但不能枚举存储帐户中的容器。

Public read access for blobs only : Blob data within this container can be read via anonymous request, but container data is not available. 仅对 blob的公共读取访问权限 :可以通过匿名请求读取此容器中的Blob数据,但是容器数据不可用。 Clients cannot enumerate blobs within the container via anonymous request. 客户端无法通过匿名请求枚举容器内的Blob。

No public read access : Container and blob data can be read by the account owner only. 没有公共读取权限 :容器和Blob数据只能由帐户所有者读取。

If the container is not private, we could set container ACL with Microsoft Azure Storage Explorer easily. 如果容器不是私有的,则可以使用Microsoft Azure Storage Explorer轻松设置容器ACL。

在此处输入图片说明

在此处输入图片说明

Updated: 更新:

By default the container permission is private, if we want to set permission for container programmatically. 默认情况下,如果我们要以编程方式设置容器权限,则容器权限为私有。 Please have a try to using the following code. 请尝试使用以下代码。

  container.SetPermissions(new BlobContainerPermissions
                {
                    PublicAccess = BlobContainerPublicAccessType.Off //private
                });

Or please have a try to create a new container and try to create and use the SAS token to access the blob again. 或者,请尝试创建一个新容器,然后尝试创建并使用SAS令牌再次访问Blob。

Update2 : Update2:

Please have a try to test with following demo code, we also could get it from Azure official document , it works correctly on my side: 请尝试使用以下演示代码进行测试,我们也可以从Azure官方文档中获取它,它在我这一方面可以正常工作:

 var connectionString = "xxxxxxxxxxxxxx"; //UseDevelopmentStorage=true
 CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);
 CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
 CloudBlobContainer container = blobClient.GetContainerReference("testcontainer");
 container.CreateIfNotExists();
 var sasBlobUri = GetBlobSasUri(container, @"C:\Tom\test.pdf");
 Console.WriteLine(sasBlobUri);
 Console.ReadKey();

 static string GetBlobSasUri(CloudBlobContainer container,string filePath)
 {

            if (!container.GetPermissions().PublicAccess.Equals(BlobContainerPublicAccessType.Off))
            {
                container.SetPermissions(new BlobContainerPermissions
                {
                    PublicAccess = BlobContainerPublicAccessType.Off
                });
            }
            var blobName = Path.GetFileName(filePath);
            //Get a reference to a blob within the container.
            CloudBlockBlob blob = container.GetBlockBlobReference(blobName);

            //Upload text to the blob. If the blob does not yet exist, it will be created.
            //If the blob does exist, its existing content will be overwritten.
            blob.UploadFromFile(filePath);

            //Set the expiry time and permissions for the blob.
            //In this case, the start time is specified as a few minutes in the past, to mitigate clock skew.
            //The shared access signature will be valid immediately.
            SharedAccessBlobPolicy sasConstraints =
                new SharedAccessBlobPolicy
                {
                    SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5),
                    SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(2), // 2 minutes expired
                    Permissions = SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.Write  //Read & Write
                };

            //Generate the shared access signature on the blob, setting the constraints directly on the signature.
            string sasBlobToken = blob.GetSharedAccessSignature(sasConstraints);

            //Return the URI string for the container, including the SAS token.
            return blob.Uri + sasBlobToken;
    }

After 2 minutes I check from the incognito chrome window. 2分钟后,我从隐身浏览器镀铬窗口中进行检查。

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM