This is the official method to validate the x-twilio-signature
. This method need to be implemented to the url (Salesforce site rest resource apex class) on which Twilio sends request to check if the request is actually from Twilio server.
public boolean validateRequest(String expectedSignature, String url, Map<String,String> params)
{
try
{
// sort the params alphabetically, and append the key and value of each to the url
String data = url;
if(params!=null)
{
List<String> sortedKeys = new List<String>(params.keySet());
sortedKeys.sort();
for (String s: sortedKeys) {
data += s;
String v='';
if (params.get(s)!=null)
v=params.get(s);
data += v;
}
}
//compute the hmac on input data bytes, with AuthToken as key
Blob mac = Crypto.generateMac('hmacSHA1', Blob.valueOf(data), Blob.valueOf(authToken));
//base64-encode the hmac
String signature = EncodingUtil.base64Encode(mac);
return signature.equals(expectedSignature);
}
catch (Exception e)
{
return false;
}
}
This is how Twilio created signature at server side:
- Turn on SSL on your server and configure your Twilio account to use HTTPS urls.
- Twilio assembles its request to your application, including the final URL and any POST fields (if the request is a POST).
- If your request is a POST, Twilio takes all the POST fields, sorts them by alphabetically by their name, and concatenates the parameter
name and value to the end of the URL (with no delimiter).
- Twilio takes the resulting string (the full URL with query string and all POST parameters) and signs it using HMAC-SHA1 and your
AuthToken as the key.
- Twilio sends this signature in an HTTP header called X-Twilio-Signature
This is how it can be validate on our end:
- Take the full URL of the request URL you specify for your phone number or app, from the protocol (https...) through the end of the
query string (everything after the ?).
- If the request is a POST, sort all of the POST parameters alphabetically (using Unix-style case-sensitive sorting order).
- Iterate through the sorted list of POST parameters, and append the variable name and value (with no delimiters) to the end of the URL
string.
- Sign the resulting string with HMAC-SHA1 using your AuthToken as the key (remember, your AuthToken's case matters!).
- Base64 encode the resulting hash value. Compare your hash to ours, submitted in the X-Twilio-Signature header. If they match, then you're
good to go.
Note: Referenced from Twilio official documentation. Method is there already, in classes/TwilioRestClient.cls