繁体   English   中英

如何为 Azure 存储生成帐户 SAS 令牌?

[英]How to generate Account SAS token for Azure Storage?

理想情况下,我想访问存储中的所有容器和 blob。 Account SAS 令牌是在我的代码中在服务器端生成的。 客户端会调用我在Node.js中创建的API来接收。 我看到您可以使用 Azure Shell 手动创建 SAS 令牌,但我更喜欢让它生成服务端,因为将实施身份验证。

帐户 SAS 生成文档之后,它指出字符串到签名应该这样构造。

StringToSign = accountname + "\n" +  
    signedpermissions + "\n" +  
    signedservice + "\n" +  
    signedresourcetype + "\n" +  
    signedstart + "\n" +  // optional
    signedexpiry + "\n" +  
    signedIP + "\n" +  // optional
    signedProtocol + "\n" +  // optional
    signedversion + "\n" 

文档中的示例令牌(为了更好的可见性而分成多行)

sv=2019-02-02&ss=bf&srt=s&st=2019-08-01T22%3A18%3A26Z
&se=2019-08-10T02%3A23%3A26Z&sr=b&sp=rw
&sip=168.1.5.60-168.1.5.70&spr=https
&sig=F%6GRVAZ5Cdj2Pw4tgU7IlSTkWgn7bUkkAg8P6HESXwmf%4B

从 Azure Shell 生成的令牌

se=2019-11-15&sp=rwdlac&sv=2018-03-28&ss=b&srt=sco&sig=<hidden signature>

奇怪的是,在示例令牌中,首先提供了signedversion (sv) ,而在来自 Azure Shell 的令牌中提供了signedexpiry (se)

下面是用于生成令牌的代码。 我尝试遵循与来自 Azure Shell 的令牌相同的顺序:

app.get('/sas-token', (req, res, next) => {

  // const start = new Date(new Date().getTime() - (15 * 60 * 1000));
  const end = new Date(new Date().getTime() + (30 * 60 * 1000));

  const signedpermissions = 'rwdlac';
  const signedversion = '2018-03-28';
  const signedservice = 'b';
  const signedresourcetype = 'sco';
  // const signedstart = truncateIsoDate(start);
  const signedexpiry = truncateIsoDate(end);
  // const signedIP = '';
  const signedProtocol = 'https';

  const StringToSign = STORAGE_ACCOUNT_NAME + "\n" +
      signedpermissions + "\n" +
      signedservice + "\n" +
      signedresourcetype + "\n" +
      // signedstart + "\n" +  
      signedexpiry + "\n" +
      // signedIP + "\n" +  
      signedProtocol + "\n" +
      signedversion + "\n"

  const key = new Buffer(ACCOUNT_ACCESS_KEY, 'base64');
  let sig = crypto.createHmac('sha256', key).update(StringToSign, 'utf8').digest('base64');

  let sas =
    `se=${signedexpiry}
     &sp=${(signedpermissions)}
     &sv=${(signedversion)}
     &ss=${(signedservice)}
     &srt=${(signedresourcetype)}
     &sig=${encodeURIComponent(sig)}`;

  res.json({
      storageUri: STORAGE_ACCOUNT_NAME,
      storageAccessToken: sas
  });
});

当我的客户最终使用生成的 SAS 令牌发出请求时,我收到一个错误:

403 (Server failed to authenticate the request. 
Make sure the value of Authorization header is formed correctly including the signature.)

是否可以为 Node.js 中的 Blob 存储生成帐户 SAS 令牌

根据我的研究,我们可以使用 Azure storage SDK azure-storage 更多详情请参考https://github.com/Azure/azure-storage-node/blob/0557d02cd2116046db1a2d7fc61a74aa28c8b557/test/accountsas-tests.js

var storage = require("azure-storage")
var startDate = new Date();
    var expiryDate = new Date();
    startDate.setTime(startDate.getTime() - 5*60*1000);
    expiryDate.setTime(expiryDate.getTime() + 24*60*60*1000);
    var AccountSasConstants = storage.Constants.AccountSasConstants;
    var sharedAccessPolicy = {
      AccessPolicy: {
        Services: AccountSasConstants.Services.BLOB ,
        ResourceTypes: AccountSasConstants.Resources.SERVICE + 
                       AccountSasConstants.Resources.CONTAINER +
                       AccountSasConstants.Resources.OBJECT,
        Permissions: AccountSasConstants.Permissions.READ + 
                     AccountSasConstants.Permissions.ADD +
                     AccountSasConstants.Permissions.CREATE +
                     AccountSasConstants.Permissions.WRITE +
                     AccountSasConstants.Permissions.DELETE +
                     AccountSasConstants.Permissions.LIST,
        Protocols: AccountSasConstants.Protocols.HTTPSORHTTP,
        Start: startDate,
        Expiry: expiryDate
      }
      
    };
    const accountname ="blobstorage0516";
    const key = "";
    var sas =storage.generateAccountSharedAccessSignature(accountname,key,sharedAccessPolicy);
    console.log(sas);

此外,如果您不想使用 SDK 生成 SAS 令牌,请注意,如果我们不使用StringToSign中的一个属性,则不能省略\n并且我们在创建 ZA8A64CEF26AB72A0 时应使用StringToSign中提供的属性。 例如

const accountname ="blobstorage0516";
    const key = "";

    const start = new Date(new Date().getTime() - (15 * 60 * 1000));
        const end = new Date(new Date().getTime() + (30 * 60 * 1000));
    const signedpermissions = 'rwdlac';
        const signedservice = 'b';
        const signedresourcetype = 'sco';
        const signedexpiry = end.toISOString().substring(0, end.toISOString().lastIndexOf('.')) + 'Z';
        const signedProtocol = 'https';
        const signedversion = '2018-03-28';

        const StringToSign =
            accountname + '\n' +
            signedpermissions + '\n' +
            signedservice + '\n' +
            signedresourcetype + '\n' +
             '\n' +
            signedexpiry + '\n' +
             '\n' +
            signedProtocol + '\n' +
      signedversion + '\n';
      
    let sig = crypto.createHmac('sha256', Buffer.from(key, 'base64')).update(StringToSign, 'utf8').digest('base64');
  
    let sasToken =
      `sv=${(signedversion)}&ss=${(signedservice)}&srt=${(signedresourcetype)}&sp=${(signedpermissions)}&se=${encodeURIComponent(signedexpiry)}&spr=${(signedProtocol)}&sig=${encodeURIComponent(sig)}`;
    console.log(sasToken)
    var storageBlobEndpoint = "https://"+ accountname +".blob.core.windows.net"
    var container="blobcontainer";
    var blobName="CP4.png";
    var requestURL = storageBlobEndpoint + "/" + container + "/" + blobName +"?"+sasToken
    console.log(requestURL)

在此处输入图像描述 在此处输入图像描述


更新

根据我的测试,我们可以使用上面代码创建的 sas 令牌对 Azure blob 存储进行 smoe 操作。 例如

1.列表容器

Get https://<your account>.blob.core.windows.net/?comp=list+ "&"+"<your sas token>"

在此处输入图像描述 在此处输入图像描述

2.获取容器属性

Get https://<your account>.blob.core.windows.net/<your container>?restype=container&comp=list +"&" +"<your sas token>"

在此处输入图像描述 此外,关于如何使用新的 sdk @azure/storage-blob创建 SAS 令牌,请参考以下代码

const accountname ="blobstorage0516";
    const key = "";
    const signedpermissions = 'rwdlac';
        const signedservice = 'b';
        const signedresourcetype = 'sco';
        
        const signedProtocol = 'https';
        const signedversion = '2018-03-28';
    const cerds = new storage.StorageSharedKeyCredential(accountname,key);
    var startDate = new Date();
    var expiryDate = new Date();
    startDate.setTime(startDate.getTime() - 5*60*1000);
    expiryDate.setTime(expiryDate.getTime() + 24*60*60*1000);
    expiryDate.setTime(expiryDate.getTime() + 24*60*60*1000);
    var result = storage.generateAccountSASQueryParameters({
      expiresOn : expiryDate,
      permissions: storage.AccountSASPermissions.parse(signedpermissions),
      protocol: storage.SASProtocol.Https,
      resourceTypes: storage.AccountSASResourceTypes.parse(signedresourcetype).toString(),
      services: storage.AccountSASServices.parse(signedservice).toString(),
      startsOn: startDate,
      version:signedversion

    },cerds).toString();
    console.log(result);
    

尝试使用@azure/storage-blob npm package

const sasString = generateAccountSASQueryParameters({... }, sharedKeyCredential).toString()

请参阅https://azuresdkdocs.blob.core.windows.net/$web/javascript/azure-storage-blob/12.0.0/globals.html#generateaccountsasqueryparameters

暂无
暂无

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

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