I'm trying to generate a CosmosDb Auth token by following the instructions here: https://docs.microsoft.com/en-us/rest/api/documentdb/access-control-on-documentdb-resources.
Here's my implementation in GoLang (I replaced all the parameters with literal values found in the "Example Encoding" section from the doc above):
import(
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"net/url")
func generateAuthToken(
verb string,
resourceType string,
resourceId string,
date string,
base64Key string) string {
// Example Key
base64Key := "dsZQi3KtZmCv1ljt3VNWNm7sQUF1y5rJfC6kv5JiwvW0EndXdDku/dkKBp8/ufDToSxLzR4y+O/0H/t4bQtVNw=="
msg := fmt.Sprintf("%s
%s
%s
%s
%s
",
"get", //verb
"dbs", //resourceId
"dbs/todolist", //resourceLink
"thu, 27 apr 2017 00:51:12 gmt", //RFC1123 date
"")
hasher := hmac.New(sha256.New, []byte(base64Key))
hasher.Write([]byte(msg))
signature := base64.StdEncoding.EncodeToString(hasher.Sum(nil))
authHeader := fmt.Sprintf("type=master&ver=1.0&sig=%s", signature)
return url.QueryEscape(authHeader)
}
I also took the C# example from the link and ran it with the same parameters as a reference.
This is what I get from the C# implementation (the reference):
"type%3Dmaster%26ver%3D1.0%26sig%3DSGWmGNFZlBH%2Bt9QCvuMy%2FVsbBAOKLbxsgy3Z7aG0PdA%3D"
And this is what I get from my GoLang implementation:
"type%3Dmaster%26ver%3D1.0%26sig%3Dwst1NDxfOeoYMurn69DgZtJUQOrgxFz%2Bp6A2vKnXxEI%3D"
Clearly I'm doing something wrong in the GoLang implementation since the two aren't identical (maybe mis-using the hashing libraries?)
For easy reference, here's the C# implementation:
static void Main(string[] args) {
string token = GenerateAuthToken(
"get",
"dbs",
"dbs/todolist",
"thu, 27 apri 2017 00:51:12 gmt",
"dsZQi3KtZmCv1ljt3VNWNm7sQUF1y5rJfC6kv5JiwvW0EndXdDku/dkKBp8/ufDToSxLzR4y+O/0H/t4bQtVNw==",
"master",
"1.0");
}
static string GenerateAuthToken(string verb, string resourceType, string resourceId, string date, string key, string keyType, string tokenVersion)
{
var hmacSha256 = new System.Security.Cryptography.HMACSHA256 { Key = Convert.FromBase64String(key) };
verb = verb ?? "";
resourceType = resourceType ?? "";
resourceId = resourceId ?? "";
string payLoad = string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}
{1}
{2}
{3}
{4}
",
verb.ToLowerInvariant(),
resourceType.ToLowerInvariant(),
resourceId,
date.ToLowerInvariant(),
"");
byte[] hashPayLoad = hmacSha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(payLoad));
string signature = Convert.ToBase64String(hashPayLoad);
return System.Net.WebUtility.UrlEncode(String.Format(System.Globalization.CultureInfo.InvariantCulture, "type={0}&ver={1}&sig={2}",
keyType,
tokenVersion,
signature));
}