错误403-尝试使用IHttpClientFactory从Azure表存储检索单个实体时



这里department是PartitionKey,id是RowKey。

错误:服务器无法对请求进行身份验证。确保Authorization标头的值格式正确,包括签名。

状态代码:禁止

如果有人能帮我解决这个错误,那就太好了。

提前感谢:(

public HttpClient getRequestHeaders(string requestType, HttpClient Newrequest, string storageAccount, string accessKey, string resource, int Length = 0)
{
HttpClient Client = Newrequest;

var RequestDateString = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
if (Client.DefaultRequestHeaders.Contains("x-ms-date"))
Client.DefaultRequestHeaders.Remove("x-ms-date");
Client.DefaultRequestHeaders.Add("x-ms-date", RequestDateString);

var requestUri = @"https://" + storageAccount + ".table.core.windows.net/" + resource;
Client.DefaultRequestHeaders.Accept.Clear();
Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
if (Client.DefaultRequestHeaders.Contains("x-ms-version"))
Client.DefaultRequestHeaders.Remove("x-ms-version");
Client.DefaultRequestHeaders.Add("x-ms-version", "2015-12-11");
if (Client.DefaultRequestHeaders.Contains("DataServiceVersion"))
Client.DefaultRequestHeaders.Remove("DataServiceVersion");
Client.DefaultRequestHeaders.Add("DataServiceVersion", "3.0;NetFx");
if (Client.DefaultRequestHeaders.Contains("MaxDataServiceVersion"))
Client.DefaultRequestHeaders.Remove("MaxDataServiceVersion");
Client.DefaultRequestHeaders.Add("MaxDataServiceVersion", "3.0;NetFx");

if (Client.DefaultRequestHeaders.Contains("Authorization"))
Client.DefaultRequestHeaders.Remove("Authorization");
var sas =  getAuthToken(Client, storageAccount, accessKey, resource);
Client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", sas);
return Client;
}

public string getAuthToken(HttpClient request, string storageAccount, string accessKey, string resource)
{
try
{
string sAuthTokn = "";
string stringToSign = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture) + "n";
stringToSign += "/" + storageAccount + "/" + resource;
HMACSHA256 hasher = new HMACSHA256(Convert.FromBase64String(accessKey));
sAuthTokn = "SharedKeyLite " + storageAccount + ":" + Convert.ToBase64String(hasher.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
return sAuthTokn;
}
catch (Exception ex)
{
throw ex;
}
}
public async Task<string> GetEntityByID(string department, string id)
{
EmployeeDetails emp = new EmployeeDetails();
string storageAccount = "sample";
string resourcePath = "SampleAzureTableStorage";
string accessKey = "<sample>";
string uri = @"https://" + storageAccount + ".table.core.windows.net/" + resourcePath + "/";
var request = _httpClientFactory.CreateClient();
request = getRequestHeaders("GET", request, storageAccount, accessKey, resourcePath);

try
{
var httpResponseMessage = await request.GetAsync(uri + department + "/" + id);
httpResponseMessage.EnsureSuccessStatusCode();
return await httpResponseMessage.Content.ReadAsStringAsync();

}
catch (WebException ex)
{
throw ex;
}
}

我相信您出现此错误的原因是因为您在代码中使用了两个不同的日期。

您将在getRequestHeaders方法中获得当前日期,然后在getAuthToken中获得不同的日期。这将导致授权标头不匹配。

我建议修改getAuthToken方法,并通过getRequestHeaders方法计算的日期/时间值。

尝试以下代码:

public HttpClient getRequestHeaders(string requestType, HttpClient Newrequest, string storageAccount, string accessKey, string resource, string partitionKey, string rowKey, int Length = 0)
{
HttpClient Client = Newrequest;

var RequestDateString = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
if (Client.DefaultRequestHeaders.Contains("x-ms-date"))
Client.DefaultRequestHeaders.Remove("x-ms-date");
Client.DefaultRequestHeaders.Add("x-ms-date", RequestDateString);

var requestUri = @"https://" + storageAccount + ".table.core.windows.net/" + resource;
Client.DefaultRequestHeaders.Accept.Clear();
Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
if (Client.DefaultRequestHeaders.Contains("x-ms-version"))
Client.DefaultRequestHeaders.Remove("x-ms-version");
Client.DefaultRequestHeaders.Add("x-ms-version", "2015-12-11");
if (Client.DefaultRequestHeaders.Contains("DataServiceVersion"))
Client.DefaultRequestHeaders.Remove("DataServiceVersion");
Client.DefaultRequestHeaders.Add("DataServiceVersion", "3.0;NetFx");
if (Client.DefaultRequestHeaders.Contains("MaxDataServiceVersion"))
Client.DefaultRequestHeaders.Remove("MaxDataServiceVersion");
Client.DefaultRequestHeaders.Add("MaxDataServiceVersion", "3.0;NetFx");

if (Client.DefaultRequestHeaders.Contains("Authorization"))
Client.DefaultRequestHeaders.Remove("Authorization");
var sas =  getAuthToken(Client, storageAccount, accessKey, resource, RequestDateString, partitionKey, rowKey);
Client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", sas);
return Client;
}

public string getAuthToken(HttpClient request, string storageAccount, string accessKey, string resource, string requestDateString, string partitionKey, string rowKey)
{
try
{
string sAuthTokn = "";
string stringToSign = requestDateString + "n";
stringToSign += "/" + storageAccount + "/" + resource +  "(PartitionKey='" + partitionKey + "',RowKey='" + rowKey + "')";
HMACSHA256 hasher = new HMACSHA256(Convert.FromBase64String(accessKey));
sAuthTokn = "SharedKeyLite " + storageAccount + ":" + Convert.ToBase64String(hasher.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
return sAuthTokn;
}
catch (Exception ex)
{
throw ex;
}
}
public async Task<string> GetEntityByID(string department, string id)
{
EmployeeDetails emp = new EmployeeDetails();
string storageAccount = "sample";
string resourcePath = "SampleAzureTableStorage";
string accessKey = "<sample>";
string uri = @"https://" + storageAccount + ".table.core.windows.net/" + resourcePath + "/";
var request = _httpClientFactory.CreateClient();
request = getRequestHeaders("GET", request, storageAccount, accessKey, resourcePath, department, id);

try
{
var httpResponseMessage = await request.GetAsync(uri + "(PartitionKey='" + department + "',RowKey='" + id + "')");
httpResponseMessage.EnsureSuccessStatusCode();
return await httpResponseMessage.Content.ReadAsStringAsync();

}
catch (WebException ex)
{
throw ex;
}
}

我认为问题出在Authorization标头中。

这是您的代码:

Client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", sas);

我认为你应该把它改成:

Client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", $"Bearer {sas}");

否则,代码看起来是正义的。

相关内容

  • 没有找到相关文章

最新更新