休息 API 调用删除实体 returns 403 错误
Rest API call for delete entity returns 403 error
以下代码旨在使用给定的分区键和行键从 table 中删除一行。但是我在 fiddler 中关注 request/response。我该如何更正错误?
请求
DELETE https://hireazurestorageacct.table.core.windows.net/mytable(PartitionKey='sample1',%20RowKey='0001')?timeout=20 HTTP/1.1
接受:application/json;odata=nometadata
x-ms-date:2017 年 5 月 8 日星期一 17:59:14 GMT
x-ms-version: 2015-04-05
Accept-Charset: UTF-8
最大数据服务版本:3.0;NetFx
数据服务版本:1.0;NetFx
If-Match: *
Content-Type: application/json
授权:SharedKeyLite hireazurestorageacct:3ZHX8lYBec+/9ytiNQb+JV5dpFkLAieuwB5veMkLVUU=
主持人:hireazurestorageacct.table.core.windows.net
回应
HTTP/1.1 403 服务器无法验证请求。确保 Authorization header 的值格式正确,包括签名。
Content-Length: 299
Content-Type: application/json
服务器:Microsoft-HTTPAPI/2.0
x-ms-request-id:a9244f7f-0002-0048-0824-c8afc5000000
日期:2017 年 5 月 8 日星期一 17:59:14 GMT
{"odata.error":{"code":"AuthenticationFailed","message":{"lang":"en-US","value": "Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.\nRequestId:a9244f7f-0002-0048-0824-c8afc5000000\nTime:2017-05-08T17:59:14.9335100Z"}}}
代码
public static int DeleteEntity(字符串 storageAccount,字符串 accessKey,字符串 tableName,字符串 partitionkey,字符串 rowkey)
{
字符串 uri = $@"https://{storageAccount}.table.core.windows.net/{tableName}(PartitionKey='{partitionkey}', RowKey='{rowkey}')?timeout=20";
字符串资源 = $@"{table名称}";
// Web request
var request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "DELETE";
request.Accept = "application/json;odata=nometadata";
request.Headers.Add("x-ms-date", DateTime.UtcNow.ToString("R", System.Globalization.CultureInfo.InvariantCulture));
request.Headers.Add("x-ms-version", "2015-04-05");
request.Headers.Add("Accept-Charset", "UTF-8");
request.Headers.Add("MaxDataServiceVersion", "3.0;NetFx");
request.Headers.Add("DataServiceVersion", "1.0;NetFx");
request.Headers.Add("If-Match", "*");
request.ContentType = "application/json";
// Signature string for Shared Key Lite Authentication must be in the form
// StringToSign = Date + "\n" + CanonicalizedResource
// Date
string stringToSign = request.Headers["x-ms-date"] + "\n";
// Canonicalized Resource in the format /{0}/{1} where 0 is name of the account and 1 is resources URI path
stringToSign += "/" + storageAccount + "/" + resource;
// Hash-based Message Authentication Code (HMAC) using SHA256 hash
var hasher = new HMACSHA256(Convert.FromBase64String(accessKey));
// Authorization header
string strAuthorization = "SharedKeyLite " + storageAccount + ":" + Convert.ToBase64String(hasher.ComputeHash(System.Text.Encoding.UTF8.GetBytes(stringToSign)));
// Add the Authorization header to the request
request.Headers.Add("Authorization", strAuthorization);
Thread.Sleep(1000);
// Execute the request
try
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (var r = new StreamReader(response.GetResponseStream()))
{
return (int)response.StatusCode;
}
}
}
catch (WebException ex)
{
// get the message from the exception response
using (var sr = new StreamReader(ex.Response.GetResponseStream()))
{
var res = sr.ReadToEnd();
// Log res if required
}
return (int)ex.Status;
}
}
状态 403 意味着您需要进行身份验证才能访问资源。任何体面的服务器都不会为您提供任何包含有关资源的任何信息的信息。因此,无论资源是否存在,您都会得到相同的答复。
根据你的代码,我猜你在使用资源生成授权令牌时,授权令牌有问题。
我建议您可以尝试使用以下代码删除 table 实体。
调用方式:
AzureTableHelper.DeleteEntity("{storageaccount}", "{accesskey}", "{tablename}", "{partitionkey}", "{rowkey}" );
删除方法:
public static int DeleteEntity(string storageAccount, string accessKey, string tableName, string partitionkey, string rowkey)
{
string host = string.Format(@"https://{0}.table.core.windows.net/", storageAccount);
string resource = string.Format(@"{0}", tableName) + string.Format("(PartitionKey='{0}',RowKey='{1}')", partitionkey, rowkey);
string uri = host + resource;
//if you want to check the etag you need firstly get the etag then delete the entity
//string jsonData = "";
//int responseCode = RequestResource(
// storageAccount,
// accessKey,
// resource,
// out jsonData);
//var jsonObject = JObject.Parse(jsonData);
//string time = jsonObject.GetValue("odata.etag").ToString();
//string time = obj.Timestamp;
// Web request
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
request.Method = "DELETE";
request.ContentType = "application/json";
request.Accept = "application/json;odata=nometadata";
request.Headers.Add("x-ms-date", DateTime.UtcNow.ToString("R", System.Globalization.CultureInfo.InvariantCulture));
request.Headers.Add("x-ms-version", "2015-04-05");
request.Headers.Add("If-Match", "*");
request.Headers.Add("Accept-Charset", "UTF-8");
request.Headers.Add("MaxDataServiceVersion", "3.0;NetFx");
request.Headers.Add("DataServiceVersion", "1.0;NetFx");
// Signature string for Shared Key Lite Authentication must be in the form
// StringToSign = Date + "\n" + CanonicalizedResource
// Date
string stringToSign = request.Headers["x-ms-date"] + "\n";
// Canonicalized Resource in the format /{0}/{1} where 0 is name of the account and 1 is resources URI path
stringToSign += "/" + storageAccount + "/" + resource;
// Hash-based Message Authentication Code (HMAC) using SHA256 hash
System.Security.Cryptography.HMACSHA256 hasher = new System.Security.Cryptography.HMACSHA256(Convert.FromBase64String(accessKey));
// Authorization header
string strAuthorization = "SharedKeyLite " + storageAccount + ":" + System.Convert.ToBase64String(hasher.ComputeHash(System.Text.Encoding.UTF8.GetBytes(stringToSign)));
// Add the Authorization header to the request
request.Headers.Add("Authorization", strAuthorization);
// Execute the request
try
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (System.IO.StreamReader r = new System.IO.StreamReader(response.GetResponseStream()))
{
string jsonResponse = r.ReadToEnd();
return (int)response.StatusCode;
}
}
}
catch (WebException ex)
{
// get the message from the exception response
using (System.IO.StreamReader sr = new System.IO.StreamReader(ex.Response.GetResponseStream()))
{
string res = sr.ReadToEnd();
// Log res if required
}
return (int)ex.Status;
}
}
以下代码旨在使用给定的分区键和行键从 table 中删除一行。但是我在 fiddler 中关注 request/response。我该如何更正错误?
请求
DELETE https://hireazurestorageacct.table.core.windows.net/mytable(PartitionKey='sample1',%20RowKey='0001')?timeout=20 HTTP/1.1 接受:application/json;odata=nometadata x-ms-date:2017 年 5 月 8 日星期一 17:59:14 GMT x-ms-version: 2015-04-05 Accept-Charset: UTF-8 最大数据服务版本:3.0;NetFx 数据服务版本:1.0;NetFx If-Match: * Content-Type: application/json 授权:SharedKeyLite hireazurestorageacct:3ZHX8lYBec+/9ytiNQb+JV5dpFkLAieuwB5veMkLVUU= 主持人:hireazurestorageacct.table.core.windows.net
回应
HTTP/1.1 403 服务器无法验证请求。确保 Authorization header 的值格式正确,包括签名。 Content-Length: 299 Content-Type: application/json 服务器:Microsoft-HTTPAPI/2.0 x-ms-request-id:a9244f7f-0002-0048-0824-c8afc5000000 日期:2017 年 5 月 8 日星期一 17:59:14 GMT
{"odata.error":{"code":"AuthenticationFailed","message":{"lang":"en-US","value": "Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.\nRequestId:a9244f7f-0002-0048-0824-c8afc5000000\nTime:2017-05-08T17:59:14.9335100Z"}}}
代码
public static int DeleteEntity(字符串 storageAccount,字符串 accessKey,字符串 tableName,字符串 partitionkey,字符串 rowkey) { 字符串 uri = $@"https://{storageAccount}.table.core.windows.net/{tableName}(PartitionKey='{partitionkey}', RowKey='{rowkey}')?timeout=20"; 字符串资源 = $@"{table名称}";
// Web request
var request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "DELETE";
request.Accept = "application/json;odata=nometadata";
request.Headers.Add("x-ms-date", DateTime.UtcNow.ToString("R", System.Globalization.CultureInfo.InvariantCulture));
request.Headers.Add("x-ms-version", "2015-04-05");
request.Headers.Add("Accept-Charset", "UTF-8");
request.Headers.Add("MaxDataServiceVersion", "3.0;NetFx");
request.Headers.Add("DataServiceVersion", "1.0;NetFx");
request.Headers.Add("If-Match", "*");
request.ContentType = "application/json";
// Signature string for Shared Key Lite Authentication must be in the form
// StringToSign = Date + "\n" + CanonicalizedResource
// Date
string stringToSign = request.Headers["x-ms-date"] + "\n";
// Canonicalized Resource in the format /{0}/{1} where 0 is name of the account and 1 is resources URI path
stringToSign += "/" + storageAccount + "/" + resource;
// Hash-based Message Authentication Code (HMAC) using SHA256 hash
var hasher = new HMACSHA256(Convert.FromBase64String(accessKey));
// Authorization header
string strAuthorization = "SharedKeyLite " + storageAccount + ":" + Convert.ToBase64String(hasher.ComputeHash(System.Text.Encoding.UTF8.GetBytes(stringToSign)));
// Add the Authorization header to the request
request.Headers.Add("Authorization", strAuthorization);
Thread.Sleep(1000);
// Execute the request
try
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (var r = new StreamReader(response.GetResponseStream()))
{
return (int)response.StatusCode;
}
}
}
catch (WebException ex)
{
// get the message from the exception response
using (var sr = new StreamReader(ex.Response.GetResponseStream()))
{
var res = sr.ReadToEnd();
// Log res if required
}
return (int)ex.Status;
}
}
状态 403 意味着您需要进行身份验证才能访问资源。任何体面的服务器都不会为您提供任何包含有关资源的任何信息的信息。因此,无论资源是否存在,您都会得到相同的答复。
根据你的代码,我猜你在使用资源生成授权令牌时,授权令牌有问题。
我建议您可以尝试使用以下代码删除 table 实体。
调用方式:
AzureTableHelper.DeleteEntity("{storageaccount}", "{accesskey}", "{tablename}", "{partitionkey}", "{rowkey}" );
删除方法:
public static int DeleteEntity(string storageAccount, string accessKey, string tableName, string partitionkey, string rowkey)
{
string host = string.Format(@"https://{0}.table.core.windows.net/", storageAccount);
string resource = string.Format(@"{0}", tableName) + string.Format("(PartitionKey='{0}',RowKey='{1}')", partitionkey, rowkey);
string uri = host + resource;
//if you want to check the etag you need firstly get the etag then delete the entity
//string jsonData = "";
//int responseCode = RequestResource(
// storageAccount,
// accessKey,
// resource,
// out jsonData);
//var jsonObject = JObject.Parse(jsonData);
//string time = jsonObject.GetValue("odata.etag").ToString();
//string time = obj.Timestamp;
// Web request
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
request.Method = "DELETE";
request.ContentType = "application/json";
request.Accept = "application/json;odata=nometadata";
request.Headers.Add("x-ms-date", DateTime.UtcNow.ToString("R", System.Globalization.CultureInfo.InvariantCulture));
request.Headers.Add("x-ms-version", "2015-04-05");
request.Headers.Add("If-Match", "*");
request.Headers.Add("Accept-Charset", "UTF-8");
request.Headers.Add("MaxDataServiceVersion", "3.0;NetFx");
request.Headers.Add("DataServiceVersion", "1.0;NetFx");
// Signature string for Shared Key Lite Authentication must be in the form
// StringToSign = Date + "\n" + CanonicalizedResource
// Date
string stringToSign = request.Headers["x-ms-date"] + "\n";
// Canonicalized Resource in the format /{0}/{1} where 0 is name of the account and 1 is resources URI path
stringToSign += "/" + storageAccount + "/" + resource;
// Hash-based Message Authentication Code (HMAC) using SHA256 hash
System.Security.Cryptography.HMACSHA256 hasher = new System.Security.Cryptography.HMACSHA256(Convert.FromBase64String(accessKey));
// Authorization header
string strAuthorization = "SharedKeyLite " + storageAccount + ":" + System.Convert.ToBase64String(hasher.ComputeHash(System.Text.Encoding.UTF8.GetBytes(stringToSign)));
// Add the Authorization header to the request
request.Headers.Add("Authorization", strAuthorization);
// Execute the request
try
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (System.IO.StreamReader r = new System.IO.StreamReader(response.GetResponseStream()))
{
string jsonResponse = r.ReadToEnd();
return (int)response.StatusCode;
}
}
}
catch (WebException ex)
{
// get the message from the exception response
using (System.IO.StreamReader sr = new System.IO.StreamReader(ex.Response.GetResponseStream()))
{
string res = sr.ReadToEnd();
// Log res if required
}
return (int)ex.Status;
}
}