Canvas Data (API) 401:Unauthorized

Jump to solution
jack0x539
Community Explorer

I'm attempting to access Canvas Data, using the API, following the guide set out by  @James  -Canvas Data API Authentication, but I'm running into a 401. Hopefully I'm just missing something simple, if anyone can see it I'd be grateful.

I'm using .NET, but the code shouldn't differ much for any other language. I've pasted my code below in case someone can spot anything untoward, or missing.

Please note that although I can't rule out there being something amiss with my GenerateHMACSignature function, it does produce the desired HMAC signature when using the example parameters given in James' article.

Generating HMAC token:

static string GenerateHMACSignature(string secret, string url, DateTime timestamp)
{
   var uri = new Uri(url);
   string query = "";
   if (uri.Query.Length > 1)
   {
      var queryParams = uri.Query.Substring(1).Split('&').OrderBy(q => q);
      query = Combine(queryParams, "&");
   }
   var parts = $"GET\n{uri.Host}\n\n\n{uri.AbsolutePath}\n{query}\n{timestamp:r}\n{secret}";

   using (HMACSHA256 hmac = new HMACSHA256(Encoding.Default.GetBytes(secret)))
   {
      var hash = hmac.ComputeHash(Encoding.Default.GetBytes(parts));
      return Convert.ToBase64String(hash);
   }  
}

Making the request:

var timestamp = DateTime.Now;
var url = "https://portal.inshosteddata.com/api/account/self/dump?limit=100&after=45";

var signature = GenerateHMACSignature(apiSecret, url, timestamp);
var request = WebRequest.CreateHttp(url);
request.Headers["Authorization"] = $"HMACAuth {apiKey}:{signature}";
request.Date = timestamp;

1 Solution
jack0x539
Community Explorer

James, 

The REST client helped me, thanks, it did come down to the time, as you said, but it's me misunderstanding the date formatting in .NET. For anyone else who cares:

DateTime.ToString("r") was returning Wed, 24 May 2017 14:57:06 GMT, which mislead me, as the time is not GMT, the time was BST (British Summer Time), yet the time zone, was still GMT.

I ended up using, DateTime.ToUniversalTime().ToString("r"), which returns Wed, 24 May 2017 13:57:06 GMT, and then it works perfectly.

Thanks for forcing me to look at the date part in detail, I was getting a little wound up with it!

View solution in original post