通过Azure File API上传文件时授权头错误问题求助
通过Azure File API上传文件时授权头错误问题求助
嘿,我之前帮好几个开发者排查过Azure File API的共享密钥签名问题,你的情况看起来就是签名字符串的构造和请求头不匹配导致的授权失败,这是个超级常见的坑,咱们一步步来理清楚:
首先,Azure共享密钥签名的核心要求是:签名字符串的每一个字段必须和你实际发送的请求头完全对应,空字段不能省略换行,x-ms开头的自定义头部必须全部按字典序加入签名。
先看你当前的问题点:
- 签名字符串里的Content-Type位置留空了,但请求头里明明设置了
Content-Type: application/binary,这会直接导致签名不匹配,因为Azure会校验这个字段的一致性。 - 你用了
x-ms-content-length这个自定义头部,但没有把它加入到签名字符串的x-ms头部区域,所有x-ms开头的头部都必须按字典序排列后加入签名,不然授权肯定过不了。 - 你混淆了
Content-Length和x-ms-content-length的作用:前者是你本次请求发送的内容长度(比如你要上传的二进制数据的大小),后者是你要创建的文件的总大小,这两个值在签名字符串里要对应不同的位置,不能搞混。
给你整理好的正确签名字符串和请求头配置:
正确的签名字符串构造
// 注意:actualContentLength是你本次请求的Content-Length值,不是x-ms-content-length的contentLength const stringToSign = `PUT\n\n\n${actualContentLength}\n\napplication/binary\n\n\n\n\n\nx-ms-content-length:${contentLength}\nx-ms-date:${currentDate}\nx-ms-type:file\nx-ms-version:2020-10-02\n/${azureStorageAccount}/${shareName}/${directoryName}/${fileName}`;
这里的关键细节:
- 第4个位置填
actualContentLength:如果是直接上传整个文件,这个值和x-ms-content-length的contentLength一致;如果只是创建空文件(后续分块上传),这个值填0。 - 第6个位置填
application/binary:完全对应你请求头里的Content-Type,不能留空。 - 所有x-ms头部按字典序排列(x-ms-content-length在x-ms-date前面,按字母顺序来),每个头部单独占一行。
- 空字段(比如Content-Encoding、Content-Language等)必须保留对应的换行,不能省略。
调整后的请求头
const headers = { 'x-ms-date': currentDate, 'x-ms-version': '2020-10-02', 'x-ms-type': 'file', 'x-ms-content-length': contentLength, 'Content-Length': actualContentLength, // 这里要和签名字符串里的actualContentLength一致 'Content-Type': 'application/binary', 'Authorization': authorizationHeader };
这里把x-ms-content-length和Content-Length明确区分开,确保两个值和签名字符串里的对应位置完全匹配。
额外的排查小技巧
- 先测试创建空文件:把
actualContentLength设为0,签名字符串里对应位置也填0,请求头的Content-Length也设为0,这样可以快速验证签名是否正确。 - 检查资源路径:签名字符串里的
/${azureStorageAccount}/${shareName}/${directoryName}/${fileName}必须和你请求的URL路径完全一致,不能多斜杠也不能少。 - 加密方式:生成授权头时,必须用HMAC-SHA256算法对签名字符串进行加密,然后Base64编码,格式是
SharedKey ${azureStorageAccount}:${编码后的签名值}。
我之前遇到好几个开发者都是因为漏加了x-ms头部或者Content-Type位置留空导致的授权错误,你按照上面的配置试试,应该能解决问题!
备注:内容来源于stack exchange,提问作者Fedir Sajbert
相关产品推荐
相关产品推荐

