在将blob(pdf文件)保存到azure blob存储时,我正在尝试实现共享访问签名。 我希望pdf文件的链接在设定的时间后过期,但它似乎不起作用。
pdf创建和保存过程运行正常,我创建了一个pdf文件并将其上传到azure blob存储。 我可以检索blob URL,如果我将其粘贴到浏览器中,则pdf报告显示正常。它永远不会过期。
我在Im测试时将到期时间设置为2分钟(生产时间约为24小时)。我可以继续查看报告,没有什么能阻止我。
我是共享签名访问的新手,但是从我到目前为止发现的,它应该在指定的时间后停止访问(这是正确的吗?)。
这就是我创建存储细节的方法(在我的类的构造函数中):
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;
}
}
这就是我生成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;
}
我可以从Azure存储资源管理器中看到blob,因此连接和生成过程很好,只是到期。
任何人都可以帮助我吗?我在这里显然做错了。
答案 0 :(得分:3)
正如Gaurav Mantri所说,你的容器似乎不是私密的。容器有3种类型的权限:public,blob,private。我们可以从Set Container ACL获得更多信息。
权限指示是否可以公开访问容器中的blob。 从2009-09-19版本开始,容器权限提供了以下用于管理容器访问的选项:
完全公开读取访问权限:可以通过匿名请求读取容器和blob数据。客户端可以通过匿名请求枚举容器中的blob,但不能枚举存储帐户中的容器。
仅对blob进行公共读取访问:可以通过匿名请求读取此容器中的Blob数据,但容器数据不可用。客户端无法通过匿名请求枚举容器中的blob。
无公开读取权限:只有帐户所有者才能读取容器和blob数据。
如果容器不是私有容器,我们可以轻松地使用Microsoft Azure Storage Explorer设置容器ACL。
<强>更新强>
默认情况下,如果我们要以编程方式设置容器权限,则容器权限是私有的。请尝试使用以下代码。
container.SetPermissions(new BlobContainerPermissions
{
PublicAccess = BlobContainerPublicAccessType.Off //private
});
或者请尝试创建一个新容器并尝试创建并使用SAS令牌再次访问blob。
更新2:
请尝试使用以下演示代码进行测试,我们也可以从Azure official document获取它,它可以在我这边正常运行:
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;
}
2分钟后,我会从隐身镀铬窗口进行检查。