理想情况下,我想访问存储中的所有容器和Blob。 我的代码在服务器端生成了帐户SAS令牌。客户端将调用我在Node.js中创建的API来接收它。我看到您可以使用Azure Shell手动创建SAS令牌,但是我希望它可以在服务端生成,因为将实现身份验证。
在account SAS generation documentation之后,它指出应该以这种方式构造符号字符串。
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存储生成 Account SAS令牌?
答案 0 :(得分:1)
根据我的研究,我们可以使用Azure存储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令牌,请注意,如果我们不使用\n
中的一个属性以及我们在其中提供的属性,则不能省略StringToSign
创建sas令牌时,应使用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操作。例如
Get https://<your account>.blob.core.windows.net/?comp=list+ "&"+"<your sas token>"
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);
答案 1 :(得分:0)
尝试使用@ azure / storage-blob npm软件包
const sasString = generateAccountSASQueryParameters({ ... },sharedKeyCredential).toString()
请参阅https://azuresdkdocs.blob.core.windows.net/ $ web / javascript / azure-storage-blob / 12.0.0 / globals.html#generateaccountsasqueryparameters