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 (SpeechletValidationException ex) {
                validationResult |= ex.ValidationResult;
            }
            catch (Exception ex)
                when(ex is 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;
                }

                if (!string.IsNullOrEmpty(ApplicationId) && result.Context.System.Application.Id != ApplicationId)
                {
                    validationResult |= SpeechletRequestValidationResult.InvalidApplicationId;
                }

                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) {
            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;
                }
            }

            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 = 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;
        }
Exemple #3
0
        /// <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 HttpResponseMessage GetResponse(HttpRequestMessage httpRequest)
        {
            DateTime now = DateTime.UtcNow; // reference time for this request

            RequestHeader requestHeader = new RequestHeader();

            requestHeader.Read(httpRequest);
            OnRequestIncome(requestHeader);

#if HasBouncyCastle
            var cerValidator = new BouncyCastleCertValidator();
#else
            var cerValidator = new DotNetCertValidator();
#endif
            var validationResult = cerValidator.Verify(requestHeader);

            if (!OnRequestValidation(requestHeader, validationResult))
            {
                return(new HttpResponseMessage(HttpStatusCode.BadRequest)
                {
                    ReasonPhrase = validationResult.ToString()
                });
            }

            try
            {
                RequestEnvelope = SpeechletRequestEnvelope.FromJson(requestHeader.RequestAsString);

                if (!SpeechletRequestTimestampVerifier.VerifyRequestTimestamp(RequestEnvelope, now))
                {
                    validationResult = validationResult | SpeechletRequestValidationResult.InvalidTimestamp;
                }
            }
            catch (Exception e1)
            {
                OnParsingError(e1);
                validationResult = SpeechletRequestValidationResult.InvalidJson;
            }


            try
            {
                string alexaResponsejson = DoProcessRequest(RequestEnvelope);
                if (alexaResponsejson == null)
                {
                    OnResponseOutgoing("->alexaResponsejson == null");

                    return(null);
                }

                OnResponseOutgoing(alexaResponsejson);

                return(new HttpResponseMessage(HttpStatusCode.OK)
                {
                    Content = new StringContent(alexaResponsejson, Encoding.UTF8, "application/json")
                });;
            }
            catch (NotImplementedException)
            {
                return(null);
            }
            catch (Exception e2)
            {
                OnParsingError(e2);
                return(new HttpResponseMessage(HttpStatusCode.InternalServerError));
            }
        }
        /// <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));
            }
        }