public ActionResult <SkillResponse> Post([FromBody] SkillRequest request) { string chainUrl = null; if (Request.Headers.Keys.Where(x => x.Equals(SpeechletRequestSignatureVerifier.Sdk.SIGNATURE_CERT_URL_REQUEST_HEADER, System.StringComparison.InvariantCultureIgnoreCase)).Any()) { chainUrl = Request.Headers.Where(x => x.Key.Equals((SpeechletRequestSignatureVerifier.Sdk.SIGNATURE_CERT_URL_REQUEST_HEADER), System.StringComparison.InvariantCultureIgnoreCase)).Select(x => x.Value.FirstOrDefault(y => !string.IsNullOrWhiteSpace(y))).FirstOrDefault(); } string signature = null; if (Request.Headers.Keys.Where(x => x.Equals(SpeechletRequestSignatureVerifier.Sdk.SIGNATURE_REQUEST_HEADER, System.StringComparison.InvariantCultureIgnoreCase)).Any()) { signature = Request.Headers.Where(x => x.Key.Equals((SpeechletRequestSignatureVerifier.Sdk.SIGNATURE_REQUEST_HEADER), System.StringComparison.InvariantCultureIgnoreCase)).Select(x => x.Value.FirstOrDefault(y => !string.IsNullOrWhiteSpace(y))).FirstOrDefault(); } Request.Body.Position = 0; using (MemoryStream memoryStream = new MemoryStream()) { Request.Body.CopyTo(memoryStream); byte[] alexaBytes = memoryStream.ToArray(); if (!_reqVerifier.VerifyRequestSignature(alexaBytes, signature, chainUrl)) { return(BadRequest()); } } return(new ActionResult <SkillResponse>(_service.ProcessRequest(request))); }
/// <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) { 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 = AsyncHelpers.RunSync <byte[]>(() => 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 (!SpeechletRequestSignatureVerifier.VerifyRequestSignature(alexaBytes, signature, chainUrl)) { validationResult = validationResult | SpeechletRequestValidationResult.InvalidSignature; } } SpeechletRequestEnvelope alexaRequest = null; try { var alexaContent = UTF8Encoding.UTF8.GetString(alexaBytes); alexaRequest = SpeechletRequestEnvelope.FromJson(alexaContent); } catch (Newtonsoft.Json.JsonReaderException) { validationResult = validationResult | SpeechletRequestValidationResult.InvalidJson; } catch (InvalidCastException) { validationResult = validationResult | SpeechletRequestValidationResult.InvalidJson; } // 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 (alexaRequest == null || !OnRequestValidation(validationResult, now, alexaRequest)) { return(new HttpResponseMessage(HttpStatusCode.BadRequest) { ReasonPhrase = validationResult.ToString() }); } string alexaResponse = DoProcessRequest(alexaRequest); HttpResponseMessage httpResponse; if (alexaResponse != null) { httpResponse = new HttpResponseMessage(HttpStatusCode.OK); httpResponse.Content = new StringContent(alexaResponse, Encoding.UTF8, "application/json"); // Debug.WriteLine(httpResponse.ToLogString()); } else { httpResponse = new HttpResponseMessage(HttpStatusCode.InternalServerError); } return(httpResponse); }
/// <summary> /// Processes Alexa request AND validates request signature /// </summary> /// <returns></returns> public virtual string GetResponse(Dictionary <string, string[]> Headers, byte[] Content, out HttpStatusCode HttpStatusCode) { SpeechletRequestValidationResult validationResult = SpeechletRequestValidationResult.OK; DateTime now = DateTime.UtcNow; // reference time for this request string chainUrl = null; if (!Headers.ContainsKey(Sdk.SIGNATURE_CERT_URL_REQUEST_HEADER) || String.IsNullOrEmpty(chainUrl = Headers[Sdk.SIGNATURE_CERT_URL_REQUEST_HEADER].First())) { validationResult = validationResult | SpeechletRequestValidationResult.NoCertHeader; } string signature = null; if (!Headers.ContainsKey(Sdk.SIGNATURE_REQUEST_HEADER) || String.IsNullOrEmpty(signature = Headers[Sdk.SIGNATURE_REQUEST_HEADER].First())) { validationResult = validationResult | SpeechletRequestValidationResult.NoSignatureHeader; } // attempt to verify signature only if we were able to locate certificate and signature headers if (validationResult == SpeechletRequestValidationResult.OK) { if (!SpeechletRequestSignatureVerifier.VerifyRequestSignature(Content, signature, chainUrl)) { validationResult = validationResult | SpeechletRequestValidationResult.InvalidSignature; } } SpeechletRequestEnvelope alexaRequest = null; try { var alexaContent = UTF8Encoding.UTF8.GetString(Content); alexaRequest = SpeechletRequestEnvelope.FromJson(alexaContent); } catch (Newtonsoft.Json.JsonReaderException) { validationResult = validationResult | SpeechletRequestValidationResult.InvalidJson; } catch (InvalidCastException) { validationResult = validationResult | SpeechletRequestValidationResult.InvalidJson; } // 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 (alexaRequest == null || !OnRequestValidation(validationResult, now, alexaRequest)) { HttpStatusCode = HttpStatusCode.BadRequest; return(validationResult.ToString()); } string alexaResponse = DoProcessRequest(alexaRequest); if (alexaResponse == null) { HttpStatusCode = HttpStatusCode.InternalServerError; return(null); } else { HttpStatusCode = HttpStatusCode.OK; return(alexaResponse); } }
/// <summary> /// Processes Alexa request AND validates request signature /// </summary> /// <param name="httpRequest"></param> /// <returns></returns> public virtual TResponse GetResponse(T httpRequest) { var validationResult = SpeechletRequestValidationResult.OK; var 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.GetValue(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.GetValue(Sdk.SIGNATURE_REQUEST_HEADER).First())) { validationResult = validationResult | SpeechletRequestValidationResult.NoSignatureHeader; } var alexaBytes = AsyncHelpers.RunSync(() => httpRequest.Content.ReadAsByteArrayAsync()); var alexaContent = Encoding.UTF8.GetString(alexaBytes); //Debug.WriteLine(httpRequest.ToLogString()); //todo // attempt to verify signature only if we were able to locate certificate and signature headers if (validationResult == SpeechletRequestValidationResult.OK) { if (!SpeechletRequestSignatureVerifier.VerifyRequestSignature(alexaBytes, signature, chainUrl)) { validationResult = validationResult | SpeechletRequestValidationResult.InvalidSignature; } } SpeechletRequestEnvelope alexaRequest = null; try { alexaRequest = SpeechletRequestEnvelope.FromJson(alexaContent); } catch (JsonReaderException) { validationResult = validationResult | SpeechletRequestValidationResult.InvalidJson; } catch (InvalidCastException) { validationResult = validationResult | SpeechletRequestValidationResult.InvalidJson; } // 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 ((alexaRequest == null) || !OnRequestValidation(validationResult, now, alexaRequest)) { var responseFactory = new TResponseFactory(); return(responseFactory.BadRequest(validationResult.ToString())); } var alexaResponse = DoProcessRequest(alexaRequest); if (alexaResponse == null) { var responseFactory = new TResponseFactory(); return(responseFactory.InternalServerError()); } else { var responseFactory = new TResponseFactory(); return(responseFactory.Ok(alexaResponse)); } }