4
votes

I am trying to authenticate a Microsoft Teams custom Bot with ColdFusion, following the Microsoft instructions in C#. I also tried following this PHP example. But I'm not having any luck. Any idea what I'm missing here?

<cfset secretKey       = "MsVx7SpJKnSiycvsUyLMiD8lDIFkEUDhuYuFAT94hXY=">
<cfset httpRequestData = GetHttpRequestData()>
<cfset c               = httpRequestData.content>
<cfset calculated_hmac = toBase64(hmac(c, secretKey, "HMACSHA256"))>

I'm getting this...

calculated_hmac: NjE2RUY1RjREQTNEMzk1Q0RBNUJDMEE2NDhFNzk3RDIyNUMzRDJDMjk5NTYzMDgxODk0NkU3Njc3RTVEQTAyQQ==

While the headers.authorization from Microsoft is this...

HMAC 6N0WyOW7g+LqShKYsouWOrPjgh0PD1gazfwNeNwpuS8=

For this specific example the GetHttpRequestData().content was...

{"type":"message","id":"1552059974228","timestamp":"2019-03-08T15:46:14.225Z","localTimestamp":"2019-03-08T09:46:14.225-06:00","serviceUrl":"https://smba.trafficmanager.net/amer/","channelId":"msteams","from":{"id":"29:1lY_4faAJwr1qSsIBSpFnI3nYpy3wv5hLp5qZk1_uuc_3ET_aW1Ttu_vN-evUZ0TXVKIBoy8wEBzPT7a1WgwOTQ","name":"Gordon Frobenius","aadObjectId":"be3510a6-204d-4b3f-b6c3-52bbddb303d5"},"conversation":{"isGroup":true,"id":"19:[email protected];messageid=1552059031619","name":null,"conversationType":"channel"},"recipient":null,"textFormat":"plain","attachmentLayout":null,"membersAdded":[],"membersRemoved":[],"topicName":null,"historyDisclosed":null,"locale":"en-US","text":"cmpro botĀ help\n","speak":null,"inputHint":null,"summary":null,"suggestedActions":null,"attachments":[{"contentType":"text/html","contentUrl":null,"content":"http://schema.skype.com/Mention\" itemid=\"0\">cmpro botĀ help\n","name":null,"thumbnailUrl":null}],"entities":[{"type":"clientInfo","locale":"en-US","country":"US","platform":"Windows"}],"channelData":{"teamsChannelId":"19:[email protected]","teamsTeamId":"19:[email protected]","channel":{"id":"19:[email protected]"},"team":{"id":"19:[email protected]"},"tenant":{"id":"0d78b7c2-75c2-4dad-966d-500250225e13"}},"action":null,"replyToId":null,"value":null,"name":null,"relatesTo":null,"code":null}

1

1 Answers

4
votes

(Note, I couldn't reproduce that "calculated_hmac" because the sample "content" string must differ in some way from the original - probably just white space, but that's enough to totally alter the result ...).

Anyway, based on the instructions, I'd guess the main issue is using strings, instead of binary, in the hashing:

  1. Generate the hmac from the request body of the message.... You will need to convert the body to a byte array in UTF8.
  2. To compute the hash, provide the byte array of the security token provided by Microsoft Teams when you registered the outgoing webhook.

First try decoding the body into binary

<cfset bodyBinary = charsetDecode(GetHttpRequestData().content, "utf-8")>

Do the same with the secret key

<cfset secretKey  = "MsVx7SpJKnSiycvsUyLMiD8lDIFkEUDhuYuFAT94hXY=">
<cfset secretBinary = binaryDecode(secretKey, "base64")>

Lastly, don't forget HMAC() returns a hexadecimal string. If you need base64, you'll have to DIY:

<cfset hexHash = hmac(bodyBinary, secretBinary, "HMACSHA256")>
<cfset calculated_hmac = binaryEncode(binaryDecode(hexHash, "hex"), "base64")>