public async Task <SpeechletRequestEnvelope> GetRequestAsync(string content, string chainUrl, string signature)
        {
            var validationResult = SpeechletRequestValidationResult.OK;

            if (string.IsNullOrEmpty(chainUrl))
            {
                validationResult |= SpeechletRequestValidationResult.NoCertHeader;
            }

            if (string.IsNullOrEmpty(signature))
            {
                validationResult |= SpeechletRequestValidationResult.NoSignatureHeader;
            }

            // attempt to verify signature only if we were able to locate certificate and signature headers
            if (validationResult == SpeechletRequestValidationResult.OK)
            {
                var alexaBytes = Encoding.UTF8.GetBytes(content);

                if (!await SpeechletRequestSignatureVerifier.VerifyRequestSignatureAsync(alexaBytes, signature, chainUrl))
                {
                    validationResult |= SpeechletRequestValidationResult.InvalidSignature;
                }
            }

            SpeechletRequestEnvelope result = null;

            try {
                result = SpeechletRequestEnvelope.FromJson(content);
            }
            catch (Exception ex)
                when(ex is Newtonsoft.Json.JsonReaderException || ex is InvalidCastException || ex is FormatException)
                {
                    validationResult |= SpeechletRequestValidationResult.InvalidJson;
                }

            var success = false;

            // attempt to verify timestamp only if we were able to parse request body
            if (result != null)
            {
                var now = DateTime.UtcNow; // reference time for this request

                if (!SpeechletRequestTimestampVerifier.VerifyRequestTimestamp(result, now))
                {
                    validationResult |= SpeechletRequestValidationResult.InvalidTimestamp;
                }

                success = speechlet?.OnRequestValidation(validationResult, now, result) ?? (validationResult == SpeechletRequestValidationResult.OK);
            }

            if (!success)
            {
                throw new SpeechletValidationException(validationResult);
            }

            return(result);
        }
        /// <summary>
        /// Processes Alexa request AND validates request signature
        /// </summary>
        /// <param name="httpRequest"></param>
        /// <returns></returns>
        public async virtual Task <HttpResponseMessage> GetResponseAsync(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 = await httpRequest.Content.ReadAsByteArrayAsync();

            Debug.WriteLine(httpRequest.ToLogString());
            if (!(await SpeechletRequestSignatureVerifier.VerifyRequestSignatureAsync(alexaBytes, signature, chainUrl)))
            {
                return(new HttpResponseMessage(HttpStatusCode.BadRequest)); // Failed signature verification
            }

            var    alexaContent  = UTF8Encoding.UTF8.GetString(alexaBytes);
            string alexaResponse = await ProcessRequestAsync(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);
        }
Esempio n. 3
0
        /// <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.Unicode, "application/json");
                Debug.WriteLine(httpResponse.ToLogString());
            }

            return(httpResponse);
        }