无法使用 SAS 令牌上传 BLOB

Can't upload BLOB with SAS Token

我有一个使用 Azure 移动应用程序构建的 Xamarin UWP 应用程序,我正在尝试使用 SAS 令牌和 .Net Azure 存储客户端 (8.4.0) 将 BLOB 上传到 Azure 存储。我可以通过 Easy API 节点函数为我的容器生成 SAS 令牌,但是当我尝试使用它上传文件时,出现错误“服务器无法验证请求。确保授权值 header 的格式正确,包括签名。"

简单API代码:用于GetUploadToken

var azure = require('azure-storage');

function generateSasToken(container, blobName, permissions) {
    var connString = "<conn string from azure storage acct>"; // removed for Whosebug question
    var blobService = azure.createBlobService(connString);

    var currentDate = new Date();
    var startDate = new Date(currentDate);
    startDate.setMinutes(currentDate.getMinutes() - 5);

    console.log("startDate:    " + startDate);

    console.log("current date: " + currentDate);

    var expiryDate = new Date(currentDate);
    expiryDate.setMinutes(currentDate.getMinutes() + 60);

    console.log("expiryDate:   " + expiryDate);    

    permissions = permissions || azure.BlobUtilities.SharedAccessPermissions.READ;

    var sharedAccessPolicy = {
        AccessPolicy: {
            Permissions: permissions,
            Start: startDate,
            Expiry: expiryDate
        }
    };

    var sasToken = blobService.generateSharedAccessSignature(container, blobName, sharedAccessPolicy);

    console.log("SAS Token: " + sasToken);
    return {
        token: sasToken,
        uri: blobService.getUrl(container, blobName, sasToken)
    };
}

module.exports = {
    "post": function (req, res, next) {
        if (req.body.Container) {
           console.log("Container: " + req.body.Container);
           console.log("BlobName:" + req.body.BlobName);
           console.log("Permissions:" + req.body.Permissions);

            // The following values can be used for permissions: 
            // "a" (Add), "r" (Read), "w" (Write), "d" (Delete), "l" (List)
            // Concatenate multiple permissions, such as "rwa" = Read, Write, Add
            var token = generateSasToken(req.body.Container, req.body.BlobName, req.body.Permissions);

            res.status(200).type('application/json').json(token);
        } else {
            res.status(400).type("text/plain").text("Specify a value for 'container");
        }
    }
};

简单API输出

Container: sketches
BlobName:DSCF3726.JPG
Permissions:rwa
startDate:    Thu Oct 05 2017 14:39:36 GMT+0000 (Coordinated Universal Time)
current date: Thu Oct 05 2017 14:44:36 GMT+0000 (Coordinated Universal Time)
expiryDate:   Thu Oct 05 2017 15:44:36 GMT+0000 (Coordinated Universal Time)
SAS Token: st=2017-10-05T14%3A39%3A36Z&se=2017-10-05T15%3A44%3A36Z&sp=rwa&sv=2017-04-17&sr=b&sig=...

上传代码

internal async Task<string> UploadAsync(string fileName, byte[] dataArray)
{
    var sketchFile = new SketchFile
    {
        BlobName = fileName,
        Container = "sketches",
        Permissions = "rwa"
    };

    var response = await CurrentClient.InvokeApiAsync<SketchFile, GetSasTokenResponse>(
        "GetUploadToken", 
        sketchFile);

    try
    {
        var blob = new CloudBlockBlob(new Uri(response.Uri));

        await blob.UploadFromByteArrayAsync(dataArray, 0, dataArray.Length);
    }
    catch (StorageException se)
    {
        System.Diagnostics.Debug.WriteLine($"Error uploading {fileName}: {se.RequestInformation.ExtendedErrorInformation.ErrorMessage}.");

        return null;
    }

    var uri = response.Uri.Substring(0, response.Uri.IndexOf('?'));

    return uri;
}

根据你的代码,我可以在我这边重现这个问题。我假设它可能是由您指定的 Permissions 引起的。 Permissions for a blob 关于 Add 权限的说明如下:

Allowed operations: Add a block to an append blob.

您可以使用 Azure Storage Explorer 并为您的块 blob 生成 sas 令牌来缩小此问题。

根据我的测试,将 Permissions 更改为 rw,然后我可以成功将我的文件上传到 azure blob 存储。