Here department is PartitionKey and id is RowKey.
Error: Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
Status Code: Forbidden
If someone could help me to resolve this error It would be great.
Thanks in advance :)
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;
}
}
CodePudding user response:
I think the problem is in your Authorization
header.
Here is your code:
Client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", sas);
I think you should change it to:
Client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", $"Bearer {sas}");
Otherwise the code looks righteous.
CodePudding user response:
I believe the reason you are getting this error is because you are using two different dates in your code.
You are getting the current date in getRequestHeaders
method and then a different date in getAuthToken
. This would cause the authorization header mismatch.
I would recommend modifying getAuthToken
method and pass the date/time value computed in getRequestHeaders
method.
Try the following code:
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;
}
}