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

使用Account SAS获取Azure Blob容器属性时认证失败

问题描述

我能成功生成Service SAS来列出容器内的Blob,但使用Account SAS获取容器属性时,返回认证失败错误:

<?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:63a5ec3b-601e-0016-4e07-4a125b000000
Time:2024-01-18T12:08:26.1877828Z</Message>
    <AuthenticationErrorDetail>Signature did not match. String to sign used was devreferenceapidatasa
rwl
b
sc
2024-01-18T12:07:27Z
2024-01-18T12:17:27Z

https
2023-11-03

</AuthenticationErrorDetail>
</Error>

我参考相关文档后写出如下JS代码:

var accountName = "reference-data";
var signedPermissions = "rwl";
var signedService = "b";
var signedStart = start;
var signedExpiry = end;
var signedResourceType = "sc";
var signedProtocol = "https";
var signedVersion = "2023-11-03";

function generateSas(storageAccountKey, input) {
    input = decodeURI(input)
    const keyBytes = CryptoJS.enc.Base64.parse(storageAccountKey)
    const hash = CryptoJS.HmacSHA256(input, keyBytes)
    const hashB64 = CryptoJS.enc.Base64.stringify(hash)
    const hashB64UriEncoded = encodeURIComponent(hashB64)
    
    return hashB64UriEncoded
}

var stringToSign = accountName + "\n" +  
    signedPermissions + "\n" +  
    signedService + "\n" +  
    signedResourceType + "\n" +  
    signedStart + "\n" +  
    signedExpiry + "\n" +  
    signedProtocol + "\n" +  
    signedVersion + "\n"

var key = MY_KEY;

const sig = generateSas(key, stringToSign)
var sasToken = `sv=${signedVersion}&ss=${signedService}&srt=${signedResourceType}&sp=${signedPermissions}&st=${signedStart}&se=${signedExpiry}&spr=${signedProtocol}&sig=${sig}`;

var url = `https://devreferenceapidatasa.blob.core.windows.net/reference-data?restype=container&${sasToken}`
问题分析与修复

从错误返回的String to sign可以定位到三个核心问题:

  1. 账户名称不匹配
    错误签名串开头是devreferenceapidatasa,但代码里的accountName写的是reference-data,必须改为存储账户的实际名称(即URL中的devreferenceapidatasa)。

  2. 签名串格式缺失必填占位行
    Azure存储账户SAS签名串(2020-02-10及以上版本)要求严格的字段顺序,即使不需要限制IP,也要保留signed-IP的空行占位。你的签名串跳过了这个字段,导致格式错位。

  3. 多余的decodeURI操作
    签名串不需要解码,直接传入原始字符串即可,去掉input = decodeURI(input)会避免破坏签名串的原始格式。

修正后的完整代码:

var accountName = "devreferenceapidatasa"; // 改为实际存储账户名称
var signedPermissions = "rwl";
var signedService = "b";
var signedStart = start;
var signedExpiry = end;
var signedResourceType = "sc";
var signedProtocol = "https";
var signedVersion = "2023-11-03";

function generateSas(storageAccountKey, input) {
    const keyBytes = CryptoJS.enc.Base64.parse(storageAccountKey)
    const hash = CryptoJS.HmacSHA256(input, keyBytes)
    const hashB64 = CryptoJS.enc.Base64.stringify(hash)
    const hashB64UriEncoded = encodeURIComponent(hashB64)
    
    return hashB64UriEncoded
}

var stringToSign = accountName + "\n" +  
    signedPermissions + "\n" +  
    signedService + "\n" +  
    signedResourceType + "\n" +  
    signedStart + "\n" +  
    signedExpiry + "\n" +  
    "" + "\n" + // 保留signed-IP的空行占位
    signedProtocol + "\n" +  
    signedVersion + "\n"

var key = MY_KEY;

const sig = generateSas(key, stringToSign)
var sasToken = `sv=${signedVersion}&ss=${signedService}&srt=${signedResourceType}&sp=${signedPermissions}&st=${signedStart}&se=${signedExpiry}&spr=${signedProtocol}&sig=${sig}`;

var url = `https://devreferenceapidatasa.blob.core.windows.net/reference-data?restype=container&${sasToken}`

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 07:02:44