/// <summary> /// Processes Alexa request AND validates request signature /// </summary> /// <param name="httpRequest"></param> /// <returns></returns> public virtual HttpResponseMessage GetResponse(HttpRequestMessage httpRequest) { if (!httpRequest.Headers.Contains(Sdk.SIGNATURE_CERT_URL_REQUEST_HEADER) || !httpRequest.Headers.Contains(Sdk.SIGNATURE_REQUEST_HEADER)) { return new HttpResponseMessage(HttpStatusCode.BadRequest); // Request signature absent } string chainUrl = httpRequest.Headers.GetValues(Sdk.SIGNATURE_CERT_URL_REQUEST_HEADER).First(); string signature = httpRequest.Headers.GetValues(Sdk.SIGNATURE_REQUEST_HEADER).First(); var alexaBytes = AsyncHelpers.RunSync<byte[]>(() => httpRequest.Content.ReadAsByteArrayAsync()); Debug.WriteLine(httpRequest.ToLogString()); if (!SpeechletRequestSignatureVerifier.VerifyRequestSignature(alexaBytes, signature, chainUrl)) { return new HttpResponseMessage(HttpStatusCode.BadRequest); // Failed signature verification } var alexaContent = UTF8Encoding.UTF8.GetString(alexaBytes); string alexaResponse = ProcessRequest(alexaContent); HttpResponseMessage httpResponse; if (alexaResponse == null) { httpResponse = new HttpResponseMessage(HttpStatusCode.InternalServerError); } else if (alexaResponse == String.Empty) { httpResponse = new HttpResponseMessage(HttpStatusCode.BadRequest); } else { httpResponse = new HttpResponseMessage(HttpStatusCode.OK); httpResponse.Content = new StringContent(alexaResponse, Encoding.UTF8, "application/json"); Debug.WriteLine(httpResponse.ToLogString()); } return httpResponse; }
/// <summary> /// Processes Alexa request AND validates request signature /// </summary> /// <param name="httpRequest"></param> /// <returns></returns> public virtual HttpResponseMessage GetResponse(HttpRequestMessage httpRequest) { var request = new ValidationRequest { HttpRequest = httpRequest, RequestTime = DateTime.UtcNow }; var response = OnRequestValidation(request); if (!response.Success) { return new HttpResponseMessage(HttpStatusCode.BadRequest) { ReasonPhrase = response.ValidationResult.ToString() }; } string alexaResponse = DoProcessRequest(response.AlexaRequest); HttpResponseMessage httpResponse; if (alexaResponse == null) { httpResponse = new HttpResponseMessage(HttpStatusCode.InternalServerError); } else { httpResponse = new HttpResponseMessage(HttpStatusCode.OK); httpResponse.Content = new StringContent(alexaResponse, Encoding.UTF8, "application/json"); Debug.WriteLine(httpResponse.ToLogString()); } return httpResponse; }
/// <summary> /// Processes Alexa request AND validates request signature /// </summary> /// <param name="httpRequest"></param> /// <returns></returns> public async virtual Task<HttpResponseMessage> GetResponseAsync(HttpRequestMessage httpRequest) { SpeechletRequestValidationResult validationResult = SpeechletRequestValidationResult.OK; DateTime now = DateTime.UtcNow; // reference time for this request string chainUrl = null; if (!httpRequest.Headers.Contains(Sdk.SIGNATURE_CERT_URL_REQUEST_HEADER) || String.IsNullOrEmpty(chainUrl = httpRequest.Headers.GetValues(Sdk.SIGNATURE_CERT_URL_REQUEST_HEADER).First())) { validationResult = validationResult | SpeechletRequestValidationResult.NoCertHeader; } string signature = null; if (!httpRequest.Headers.Contains(Sdk.SIGNATURE_REQUEST_HEADER) || String.IsNullOrEmpty(signature = httpRequest.Headers.GetValues(Sdk.SIGNATURE_REQUEST_HEADER).First())) { validationResult = validationResult | SpeechletRequestValidationResult.NoSignatureHeader; } var alexaBytes = await httpRequest.Content.ReadAsByteArrayAsync(); Debug.WriteLine(httpRequest.ToLogString()); // attempt to verify signature only if we were able to locate certificate and signature headers if (validationResult == SpeechletRequestValidationResult.OK) { if (!(await SpeechletRequestSignatureVerifier.VerifyRequestSignatureAsync(alexaBytes, signature, chainUrl))) { validationResult = validationResult | SpeechletRequestValidationResult.InvalidSignature; } } var alexaContent = UTF8Encoding.UTF8.GetString(alexaBytes); var alexaRequest = SpeechletRequestEnvelope.FromJson(alexaContent); // attempt to verify timestamp only if we were able to parse request body if (alexaRequest != null) { if (!SpeechletRequestTimestampVerifier.VerifyRequestTimestamp(alexaRequest, now)) { validationResult = validationResult | SpeechletRequestValidationResult.InvalidTimestamp; } } if (!OnRequestValidation(validationResult, now, alexaRequest)) { return new HttpResponseMessage(HttpStatusCode.BadRequest) { ReasonPhrase = validationResult.ToString() }; } string alexaResponse = await DoProcessRequestAsync(alexaRequest); HttpResponseMessage httpResponse; if (alexaResponse == null) { httpResponse = new HttpResponseMessage(HttpStatusCode.InternalServerError); } else { httpResponse = new HttpResponseMessage(HttpStatusCode.OK); httpResponse.Content = new StringContent(alexaResponse, Encoding.UTF8, "application/json"); Debug.WriteLine(httpResponse.ToLogString()); } return httpResponse; }