Reputation: 25
I'm attempting to validate a message from slack through my AWS API Gateway, an example of what I'm passing to my Lambda function is
{'method': 'POST', 'body': {'token': 'xxxxxx', 'team_id': 'xxxxxx', 'api_app_id': 'xxxxxx', 'event': {'client_msg_id': 'xxxxxx-xxxxxx-xxxxxx-xxxxxx-xxxxxx', 'type': 'message', 'text': 'test', 'user': 'xxxxxx', 'ts': 'xxxxxx.xxxx', 'team': 'xxxxxx', 'blocks': [{'type': 'rich_text', 'block_id': 'xxx', 'elements': [{'type': 'rich_text_section', 'elements': [{'type': 'text', 'text': 'test'}]}]}], 'channel': 'xxxxxx', 'event_ts': 'xxxxxx.xxxx', 'channel_type': 'im'}, 'type': 'event_callback', 'event_id': 'xxxxxxxxx', 'event_time': 1576188370, 'authed_users': ['xxxxxxx']}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip,deflate', 'Content-Type': 'application/json', 'Host': 'xxxxxxxxxx.execute-api.us-east-1.amazonaws.com', 'User-Agent': 'Slackbot 1.0 (+https://api.slack.com/robots)', 'X-Amzn-Trace-Id': 'Root=1-xxxxxx-xxxxxxxxx', 'X-Forwarded-For': '54.xxx.xxx.xxx', 'X-Forwarded-Port': '443', 'X-Forwarded-Proto': 'https', 'X-Slack-Request-Timestamp': '1576188371', 'X-Slack-Signature': 'v0=xxxxxxxxxxxxxxxxxxxxxxxx'}}
An excerpt of just the body/request_body
{'token': 'xxxxxx', 'team_id': 'xxxxxx', 'api_app_id': 'xxxxxx', 'event': {'client_msg_id': 'xxxxxx-xxxxxx-xxxxxx-xxxxxx-xxxxxx', 'type': 'message', 'text': 'test', 'user': 'xxxxxx', 'ts': 'xxxxxx.xxxx', 'team': 'xxxxxx', 'blocks': [{'type': 'rich_text', 'block_id': 'xxx', 'elements': [{'type': 'rich_text_section', 'elements': [{'type': 'text', 'text': 'test'}]}]}], 'channel': 'xxxxxx', 'event_ts': 'xxxxxx.xxxx', 'channel_type': 'im'}, 'type': 'event_callback', 'event_id': 'xxxxxxxxx', 'event_time': 1576188370, 'authed_users': ['xxxxxxx']}
I'm pulling out the X-Slack-Signature, X-Slack-Request-Timestamp, and the body of the object, then passing it to the following function
def verify_slack_request(slack_signature=None, slack_request_timestamp=None, request_body=None):
slack_signing_secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxx'
print(request_body)
data_body = json.dumps(request_body)
basestring = 'v0:' + slack_request_timestamp + ':' + json.dumps(request_body, indent=None)
slack_signing_secret = bytes(slack_signing_secret, 'utf-8')
unicode_basestring = bytes(basestring, 'utf-8')
my_signature = 'v0=' + hmac.new(slack_signing_secret, unicode_basestring, hashlib.sha256).hexdigest()
print(my_signature)
print(slack_signature)
The issue I'm having is that the slack signature passed with the method and my signature do not line up, I've been able to verify slack slash commands but general chat commands don't seem to be working using this method.
Upvotes: 0
Views: 867
Reputation: 8593
The problem was json.dumps
does not remove spaces between keys and values. The function need a separators
parameter to remove spaces
Try the following code, you should pass pass the body of the lambda event as a dict (not string) to this function.
import json
import hashlib
import hmac
def create_signature(secret, timestamp, data):
newdata =json.dumps(data, separators=(',', ':'))
req = ('v0:' + str(timestamp) + ':' + newdata).encode()
print('sigBaseString: ', req)
request_signature= 'v0='+hmac.new(
str.encode(secret),
req, hashlib.sha256
).hexdigest()
return request_signature
Upvotes: 1