You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用生成的容器级SAS Token无法认证Azure Blob存储的问题

Azure Functions生成容器级SAS Token遇认证失败问题及解决

问题详情

我使用Azure Functions生成容器级别的SAS Token,初始实现代码如下:

const {
  StorageSharedKeyCredential,
  ContainerSASPermissions,
  SASProtocol,
  generateBlobSASQueryParameters,
} = require('@azure/storage-blob');
require('dotenv').config();
const {STORAGE_ACCOUNT_NAME, STORAGE_ACCOUNT_KEY1} = process.env;

const constants = {
  accountName: STORAGE_ACCOUNT_NAME,
  accountKey: STORAGE_ACCOUNT_KEY1
};

const sharedKeyCredential = new StorageSharedKeyCredential(
  constants.accountName,
  constants.accountKey
);

async function createContainerSas(containerName) {
  const sasOptions = {
    containerName,
    permissions: ContainerSASPermissions.parse("racwli"),
    startsOn: new Date(),
    expiresOn: new Date(new Date().valueOf() + 86400000),
    protocol: SASProtocol.Https,
  };

  const sasToken = generateBlobSASQueryParameters(sasOptions, sharedKeyCredential).toString();
  return sasToken;
}

module.exports = async function (context, req) {
  const sasToken = await createContainerSas(req.query.containerName);
  context.res = {
    body: {
      sasToken
    }
  };
};

我在本地及部署环境中使用以下URL调用:
http://localhost:7071/api/blobstorage-controller/{CONTAINER_NAME}?comp=list&restype=container&{GENERATED_SAS_TOKEN}

但收到认证失败错误:

<?xml version="1.0" encoding="utf-8"?> 
<Error>    
  <Code>AuthenticationFailed</Code>    
  <Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. RequestId:0986c9be-d01e-000b-37ba-27627d000000 Time:2023-12-05T20:34:10.2329768Z</Message>    
  <AuthenticationErrorDetail>Signature fields not well formed.</AuthenticationErrorDetail> 
</Error>

注:通过Azure门户生成的Token可以正常使用,我期望仅通过SAS Token实现认证。

可行替代方案

采用连接字符串的方式实现,代码如下:

const {
  StorageSharedKeyCredential,
  ContainerSASPermissions,
  generateBlobSASQueryParameters
} = require("@azure/storage-blob");
require('dotenv').config()
const { extractConnectionStringParts } = require('./utils.js');
const {STORAGE_CONNECTION_STRING}= process.env;

module.exports = async function (context, req) {  
  const reqPermissions = (req.query.permissions || req.body.permissions || 'rwl').split('');
  const permissionsOrder = ["r", "a", "c", "w", "d", "x", "y", "l", "t", "m", "e", "o", "p"]; 
  const permissions = reqPermissions.sort((a, b) => {
      return (
          permissionsOrder.indexOf(a) - permissionsOrder.indexOf(b)
      );
  }).join('');

  console.log(permissions);

  const container = req.query.containerName || req.body.containerName;
  context.res = {
      body: generateSasToken(STORAGE_CONNECTION_STRING, container, permissions)
  };
};

function generateSasToken(connectionString, container, permissions) {
  const { accountKey, accountName } = extractConnectionStringParts(connectionString);
  const sharedKeyCredential = new StorageSharedKeyCredential(accountName, accountKey.toString('base64'));

  let expiryDate = new Date();
  expiryDate.setHours(expiryDate.getHours() + 24);

  const sasToken = generateBlobSASQueryParameters({
      containerName: container,
      permissions: ContainerSASPermissions.parse(permissions),
      expiresOn: expiryDate,
  }, sharedKeyCredential);

  return {
      sasToken: sasToken.toString(),
  };
}

目前该替代方案可以正常工作。

内容的提问来源于stack exchange,提问作者Rene Souza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 12:04:51