Azure Table Storage使用StringToSign生成SAS令牌失败求助
Azure Table Storage SAS令牌生成无效排查与修复
问题描述
按照官方文档的StringToSign方法生成Azure Table Storage的SAS令牌,但令牌始终无效,调用时报错:
Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature
尝试的C#代码如下:
private static string GenerateTableSasToken(string storageAccountName, string tableName) { string start = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ"); string expiry = DateTime.UtcNow.AddHours(1).ToString("yyyy-MM-ddTHH:mm:ssZ"); string stringToSign = $"r\n"+ $"{start}\n"+ $"{expiry}\n" + $"/table/{storageAccountName}/{tableName}\n"+ "\n"+ "\n"+ "\n"+ $"2019-02-02\n" + "\n"+ "\n"+ "\n"+ "\n"; Console.WriteLine(stringToSign); string signature = CreateHMACSHA256Signature(stringToSign, storageAccountKey); return $"https://{storageAccountName}.table.core.windows.net/{tableName}(PartitionKey='Failed',RowKey='207b71')" + $"?sv=2019-02-02&tn=logging&st={start}&se={expiry}&sp=r&sig={Uri.EscapeDataString(signature)}"; } private static string CreateHMACSHA256Signature(string stringToSign, string storageAccountKey) { byte[] key = Convert.FromBase64String(storageAccountKey); using (HMACSHA256 hmac = new HMACSHA256(key)) { byte[] dataToHmac = Encoding.UTF8.GetBytes(stringToSign); return Convert.ToBase64String(hmac.ComputeHash(dataToHmac)); } }
核心问题
代码存在3处关键错误,导致签名验证失败:
StringToSign字段顺序缺失/错误
Table服务SAS的StringToSign必须严格遵循官方定义的字段顺序,你漏了signedResource(值为t,表示表资源)以及后续的重复权限、时间等字段,空字段也必须保留换行,少任何一行都会导致签名不匹配。SAS参数错误
- 返回URL中硬编码了
tn=logging,实际应使用传入的tableName,参数不匹配会触发权限验证失败; - 缺少
sr=t参数,这是Table服务SAS必须的资源类型标识。
- 返回URL中硬编码了
参数未编码
起始时间st和过期时间se包含冒号等特殊字符,未进行URL编码会导致服务端解析错误。
修复后的代码
private static string GenerateTableSasToken(string storageAccountName, string tableName, string storageAccountKey) { string permissions = "r"; string start = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ"); string expiry = DateTime.UtcNow.AddHours(1).ToString("yyyy-MM-ddTHH:mm:ssZ"); string signedVersion = "2019-02-02"; string signedResource = "t"; // 严格按照官方字段顺序构建StringToSign,空字段保留换行 string stringToSign = $"{permissions}\n" + $"{start}\n" + $"{expiry}\n" + $"/table/{storageAccountName}/{tableName}\n" + "\n" + // 标识符(si),无则为空 "\n" + // IP范围(sip),无则为空 "\n" + // 协议(spr),无则为空 $"{signedVersion}\n" + $"{signedResource}\n" + $"{permissions}\n" + $"{start}\n" + $"{expiry}\n" + "\n" + // SignedIP,无则为空 "\n"; // SignedProtocol,无则为空 string signature = CreateHMACSHA256Signature(stringToSign, storageAccountKey); // 对参数进行URL编码,补充缺失参数,修正表名参数 return $"https://{storageAccountName}.table.core.windows.net/{tableName}(PartitionKey='Failed',RowKey='207b71')" + $"?sv={signedVersion}&tn={tableName}&st={Uri.EscapeDataString(start)}&se={Uri.EscapeDataString(expiry)}&sp={permissions}&sr={signedResource}&sig={Uri.EscapeDataString(signature)}"; } private static string CreateHMACSHA256Signature(string stringToSign, string storageAccountKey) { byte[] key = Convert.FromBase64String(storageAccountKey); using (HMACSHA256 hmac = new HMACSHA256(key)) { byte[] dataToHmac = Encoding.UTF8.GetBytes(stringToSign); return Convert.ToBase64String(hmac.ComputeHash(dataToHmac)); } }
验证要点
- 确认
storageAccountKey是存储账户的有效访问密钥,无多余空格或格式错误; - 输出
stringToSign,逐行对照官方文档确认字段顺序和空行是否正确; - 确保所有URL参数(st、se、sig)都经过
Uri.EscapeDataString编码。
内容的提问来源于stack exchange,提问作者Arm
相关产品推荐
相关产品推荐

