在 Azure 文件服务 REST Api 上调用创建文件
Call Create File on Azure File Service REST Api
我正在尝试在 Azure 文件服务中创建一个文件:
https://docs.microsoft.com/en-us/rest/api/storageservices/create-file
我已经看到并阅读了有关此问题的多个线程,但我无法弄清楚我的情况可能是什么问题...很可能我在请求中遗漏了一些我找不到的小东西.
我得到的错误:在 HTTP 请求中找到的 MAC 签名 (...) 与任何计算签名不同。
我用过的签名串:
PUT
\n
\n
\n
\n
text/plain // Content-Type
\n
\n
\n
\n
\n
\n
x-ms-content-length:1000
x-ms-date:Tue, 20 Apr 2021 19:23:30 GMT
x-ms-type:file
x-ms-version:2015-02-21
/account/share/test
授权header:
SharedKey account:XXXXXXXXXX
我使用 HMACSHA256 对授权 header 和签名字符串进行哈希处理,当我使用其他端点(列表共享:https://docs.microsoft.com/en-us/rest/api/storageservices/list-shares), but I can't make it work for the file. I've seen this topic AZURE File Service - Upload PDF through REST API 并且我相信我正在使用非常相似的请求,但没有成功...
感谢任何帮助:)
编辑:
我不确定我是否正确设置了内容 headers。例如, x-ms-content-length 是否应该放在 CanonicalizedHeaders 字符串中?
编辑2:
关于 Ivan Yang 写的,我使代码可以工作,但只有当我的 CanonicalizedHeaders 是这样构建的时候:
CanonicalizedHeaders := 'x-ms-content-length:1200'
+ LF + 'x-ms-date:' + UTCDateTimeText
+ LF + 'x-ms-file-attributes:Archive' + LF + 'x-ms-file-creation-time:Now' + LF + 'x-ms-file-last-write-time:Now' + LF + 'x-ms-file-permission:Inherit'
+ LF + 'x-ms-type:file' + LF + 'x-ms-version:2019-02-02';
如果我按不同的顺序排列它们,它就会崩溃:
CanonicalizedHeaders := 'x-ms-date:' + UTCDateTimeText + LF +
'x-ms-content-length:1200' + LF +
'x-ms-version:2019-02-02' + LF +
'x-ms-file-attributes:Archive' + LF +
'x-ms-file-creation-time:Now' + LF +
'x-ms-file-last-write-time:Now' + LF +
'x-ms-file-permission:Inherit' + LF +
'x-ms-type:file';
这怎么会有所不同?
您的签名字符串不正确(您遗漏了一些 "\n"
)。我使用的是 x-ms-version:2019-02-02
而不是旧的 x-ms-version:2015-02-21
,正确的签名字符串应该如下所示:
"PUT\n"
+ "\n" // content encoding
+ "\n" // content language
+ "\n" // content length
+ "\n" // content md5
+ content_type + "\n" // content type
+ "\n" // date
+ "\n" // if modified since
+ "\n" // if match
+ "\n" // if none match
+ "\n" // if unmodified since
+ "\n" // range
+ "x-ms-content-length:" + content_length
+ "\nx-ms-date:" + dt.ToString("R")
+ "\nx-ms-file-attributes:Archive" + "\nx-ms-file-creation-time:Now" + "\nx-ms-file-last-write-time:Now" + "\nx-ms-file-permission:Inherit"
+ "\nx-ms-type:file" + "\nx-ms-version:" + apiversion + "\n" // headers
+ "/{0}/{1}/{2}", Account, FileShare, FileName);
这里是 c# code
使用 create file api:
using System;
using System.Globalization;
using System.Net;
using System.Security.Cryptography;
namespace ConsoleApp25
{
class Program
{
static void Main(string[] args)
{
string Account = "storage_account_name";
string Key = "storage_account_key";
string FileShare = "file_share_name";
string FileName = "test555.txt";
string apiversion = "2019-02-02";
int content_length = 1200;
string content_type = "text/plain";
DateTime dt = DateTime.UtcNow;
string StringToSign = String.Format("PUT\n"
+ "\n" // content encoding
+ "\n" // content language
+ "\n" // content length
+ "\n" // content md5
+ content_type + "\n" // content type
+ "\n" // date
+ "\n" // if modified since
+ "\n" // if match
+ "\n" // if none match
+ "\n" // if unmodified since
+ "\n" // range
+ "x-ms-content-length:" + content_length
+ "\nx-ms-date:" + dt.ToString("R")
+ "\nx-ms-file-attributes:Archive" + "\nx-ms-file-creation-time:Now" + "\nx-ms-file-last-write-time:Now" + "\nx-ms-file-permission:Inherit"
+ "\nx-ms-type:file" + "\nx-ms-version:" + apiversion + "\n" // headers
+ "/{0}/{1}/{2}", Account, FileShare, FileName);
string auth = SignThis(StringToSign, Key, Account);
string method = "PUT";
string urlPath = string.Format("https://{0}.file.core.windows.net/{1}/{2}", Account, FileShare, FileName);
Uri uri = new Uri(urlPath);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = method;
request.ContentLength = 0;
request.Headers.Add("x-ms-content-length", $"{content_length}");
request.Headers.Add("Content-Type", content_type);
request.Headers.Add("x-ms-type", "file");
request.Headers.Add("x-ms-date", dt.ToString("R"));
request.Headers.Add("x-ms-version", apiversion);
request.Headers.Add("x-ms-file-attributes", "Archive"); //note it is case-sensitive.
request.Headers.Add("x-ms-file-permission", "Inherit");
request.Headers.Add("x-ms-file-creation-time", "Now");
request.Headers.Add("x-ms-file-last-write-time", "Now");
request.Headers.Add("Authorization", auth);
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
//read the response code
Console.WriteLine("the response is:" + response.StatusCode);
}
Console.WriteLine("**completed**");
Console.ReadLine();
}
private static String SignThis(String StringToSign, string Key, string Account)
{
String signature = string.Empty;
byte[] unicodeKey = Convert.FromBase64String(Key);
using (HMACSHA256 hmacSha256 = new HMACSHA256(unicodeKey))
{
Byte[] dataToHmac = System.Text.Encoding.UTF8.GetBytes(StringToSign);
signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
}
String authorizationHeader = String.Format(
CultureInfo.InvariantCulture,
"{0} {1}:{2}",
"SharedKey",
Account,
signature);
return authorizationHeader;
}
}
}
我正在尝试在 Azure 文件服务中创建一个文件: https://docs.microsoft.com/en-us/rest/api/storageservices/create-file
我已经看到并阅读了有关此问题的多个线程,但我无法弄清楚我的情况可能是什么问题...很可能我在请求中遗漏了一些我找不到的小东西.
我得到的错误:在 HTTP 请求中找到的 MAC 签名 (...) 与任何计算签名不同。
我用过的签名串:
PUT
\n
\n
\n
\n
text/plain // Content-Type
\n
\n
\n
\n
\n
\n
x-ms-content-length:1000
x-ms-date:Tue, 20 Apr 2021 19:23:30 GMT
x-ms-type:file
x-ms-version:2015-02-21
/account/share/test
授权header:
SharedKey account:XXXXXXXXXX
我使用 HMACSHA256 对授权 header 和签名字符串进行哈希处理,当我使用其他端点(列表共享:https://docs.microsoft.com/en-us/rest/api/storageservices/list-shares), but I can't make it work for the file. I've seen this topic AZURE File Service - Upload PDF through REST API 并且我相信我正在使用非常相似的请求,但没有成功...
感谢任何帮助:)
编辑: 我不确定我是否正确设置了内容 headers。例如, x-ms-content-length 是否应该放在 CanonicalizedHeaders 字符串中?
编辑2: 关于 Ivan Yang 写的,我使代码可以工作,但只有当我的 CanonicalizedHeaders 是这样构建的时候:
CanonicalizedHeaders := 'x-ms-content-length:1200'
+ LF + 'x-ms-date:' + UTCDateTimeText
+ LF + 'x-ms-file-attributes:Archive' + LF + 'x-ms-file-creation-time:Now' + LF + 'x-ms-file-last-write-time:Now' + LF + 'x-ms-file-permission:Inherit'
+ LF + 'x-ms-type:file' + LF + 'x-ms-version:2019-02-02';
如果我按不同的顺序排列它们,它就会崩溃:
CanonicalizedHeaders := 'x-ms-date:' + UTCDateTimeText + LF +
'x-ms-content-length:1200' + LF +
'x-ms-version:2019-02-02' + LF +
'x-ms-file-attributes:Archive' + LF +
'x-ms-file-creation-time:Now' + LF +
'x-ms-file-last-write-time:Now' + LF +
'x-ms-file-permission:Inherit' + LF +
'x-ms-type:file';
这怎么会有所不同?
您的签名字符串不正确(您遗漏了一些 "\n"
)。我使用的是 x-ms-version:2019-02-02
而不是旧的 x-ms-version:2015-02-21
,正确的签名字符串应该如下所示:
"PUT\n"
+ "\n" // content encoding
+ "\n" // content language
+ "\n" // content length
+ "\n" // content md5
+ content_type + "\n" // content type
+ "\n" // date
+ "\n" // if modified since
+ "\n" // if match
+ "\n" // if none match
+ "\n" // if unmodified since
+ "\n" // range
+ "x-ms-content-length:" + content_length
+ "\nx-ms-date:" + dt.ToString("R")
+ "\nx-ms-file-attributes:Archive" + "\nx-ms-file-creation-time:Now" + "\nx-ms-file-last-write-time:Now" + "\nx-ms-file-permission:Inherit"
+ "\nx-ms-type:file" + "\nx-ms-version:" + apiversion + "\n" // headers
+ "/{0}/{1}/{2}", Account, FileShare, FileName);
这里是 c# code
使用 create file api:
using System;
using System.Globalization;
using System.Net;
using System.Security.Cryptography;
namespace ConsoleApp25
{
class Program
{
static void Main(string[] args)
{
string Account = "storage_account_name";
string Key = "storage_account_key";
string FileShare = "file_share_name";
string FileName = "test555.txt";
string apiversion = "2019-02-02";
int content_length = 1200;
string content_type = "text/plain";
DateTime dt = DateTime.UtcNow;
string StringToSign = String.Format("PUT\n"
+ "\n" // content encoding
+ "\n" // content language
+ "\n" // content length
+ "\n" // content md5
+ content_type + "\n" // content type
+ "\n" // date
+ "\n" // if modified since
+ "\n" // if match
+ "\n" // if none match
+ "\n" // if unmodified since
+ "\n" // range
+ "x-ms-content-length:" + content_length
+ "\nx-ms-date:" + dt.ToString("R")
+ "\nx-ms-file-attributes:Archive" + "\nx-ms-file-creation-time:Now" + "\nx-ms-file-last-write-time:Now" + "\nx-ms-file-permission:Inherit"
+ "\nx-ms-type:file" + "\nx-ms-version:" + apiversion + "\n" // headers
+ "/{0}/{1}/{2}", Account, FileShare, FileName);
string auth = SignThis(StringToSign, Key, Account);
string method = "PUT";
string urlPath = string.Format("https://{0}.file.core.windows.net/{1}/{2}", Account, FileShare, FileName);
Uri uri = new Uri(urlPath);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = method;
request.ContentLength = 0;
request.Headers.Add("x-ms-content-length", $"{content_length}");
request.Headers.Add("Content-Type", content_type);
request.Headers.Add("x-ms-type", "file");
request.Headers.Add("x-ms-date", dt.ToString("R"));
request.Headers.Add("x-ms-version", apiversion);
request.Headers.Add("x-ms-file-attributes", "Archive"); //note it is case-sensitive.
request.Headers.Add("x-ms-file-permission", "Inherit");
request.Headers.Add("x-ms-file-creation-time", "Now");
request.Headers.Add("x-ms-file-last-write-time", "Now");
request.Headers.Add("Authorization", auth);
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
//read the response code
Console.WriteLine("the response is:" + response.StatusCode);
}
Console.WriteLine("**completed**");
Console.ReadLine();
}
private static String SignThis(String StringToSign, string Key, string Account)
{
String signature = string.Empty;
byte[] unicodeKey = Convert.FromBase64String(Key);
using (HMACSHA256 hmacSha256 = new HMACSHA256(unicodeKey))
{
Byte[] dataToHmac = System.Text.Encoding.UTF8.GetBytes(StringToSign);
signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
}
String authorizationHeader = String.Format(
CultureInfo.InvariantCulture,
"{0} {1}:{2}",
"SharedKey",
Account,
signature);
return authorizationHeader;
}
}
}