1
votes

My entire C#/Twilio application has been using HTTPS with Basic Authentication flawlessly up until this point. I'm using the C# TwiML wrapper classes to create and return a dial TwiML Command.

    var helper = new UrlHelper(Request.RequestContext);
    var recordingUri = helper.ActionUri("Process", "RecordingCallBack");
    var vr = new VoiceResponse();
    var dial = new Dial("xxx-xxx-xxxx", record: record, timeout: 15,recordingStatusCallback: recordingUri, 
            recordingStatusCallbackEvent: recEvent, recordingStatusCallbackMethod:HttpMethod.Get);
    return TwiML(vr.Append(dial));

The issue is that the recordingStatusCallback is being returned a 401 Unauthorized and subsequent request with the appropriate credentials is never being sent. When I move my action to an unprotected controller the request processes fine but I don't want to leave this end point exposed. How can I configure the recording call back url with basic auth?

1
There is way using which you can verify if the request is coming from twilio. Twilio signs the request using the clietnid and secret, you can verify the signature at your end using the same approach and allow the request processing if its valid. - Chetan

1 Answers

1
votes

Using the above comments from @Chetan Ranpariya I created the below Validation Attribute:

[AttributeUsage(AttributeTargets.Method)]
public class ValidateTwilioRequestAttribute : ActionFilterAttribute
{
    private readonly RequestValidator _requestValidator;

    public ValidateTwilioRequestAttribute()
    {
        var authToken = ConfigurationManager.AppSettings["TwilioAuthToken"];
        _requestValidator = new RequestValidator(authToken);
    }

    public override void OnActionExecuting(ActionExecutingContext actionContext)
    {
        var context = actionContext.HttpContext;
        if (!IsValidRequest(context.Request))
        {
            actionContext.Result = new HttpStatusCodeResult(HttpStatusCode.Forbidden);
        }

        base.OnActionExecuting(actionContext);
    }

    private bool IsValidRequest(HttpRequestBase request)
    {
        var signature = request.Headers["X-Twilio-Signature"];
        var requestUrl = request.Url.AbsoluteUri;
        return _requestValidator.Validate(requestUrl, request.Form, signature);
    }
}

And decorated my call back Action accordingly:

    [ValidateTwilioRequest]
    public ActionResult Process()
    {
       //do call back work
    }