private async Task <bool> ValidateRequest(HttpRequest request, SkillRequest skillRequest) { try { request.Headers.TryGetValue("SignatureCertChainUrl", out var signatureChainUrl); if (string.IsNullOrWhiteSpace(signatureChainUrl)) { return(false); } Uri certUrl; try { certUrl = new Uri(signatureChainUrl); } catch { return(false); } request.Headers.TryGetValue("Signature", out var signature); if (string.IsNullOrWhiteSpace(signature)) { return(false); } var body = ""; request.EnableRewind(); using (var stream = new StreamReader(request.Body)) { stream.BaseStream.Position = 0; body = stream.ReadToEnd(); stream.BaseStream.Position = 0; } if (string.IsNullOrWhiteSpace(body)) { return(false); } bool isTimestampValid = RequestVerification.RequestTimestampWithinTolerance(skillRequest); bool valid = await RequestVerification.Verify(signature, certUrl, body); if (!valid || !isTimestampValid) { return(false); } else { return(true); } } catch { return(false); } }
private static async Task <bool> ValidateRequest(HttpRequest request, ILogger log, SkillRequest skillRequest) { request.Headers.TryGetValue("SignatureCertChainUrl", out var signatureChainUrl); if (string.IsNullOrWhiteSpace(signatureChainUrl)) { log.LogError("Validation failed. Empty SignatureCertChainUrl header"); return(false); } Uri certUrl; try { certUrl = new Uri(signatureChainUrl); } catch { log.LogError($"Validation failed. SignatureChainUrl not valid: {signatureChainUrl}"); return(false); } request.Headers.TryGetValue("Signature", out var signature); if (string.IsNullOrWhiteSpace(signature)) { log.LogError("Validation failed - Empty Signature header"); return(false); } request.Body.Position = 0; var body = await request.ReadAsStringAsync(); request.Body.Position = 0; if (string.IsNullOrWhiteSpace(body)) { log.LogError("Validation failed - the JSON is empty"); return(false); } bool isTimestampValid = RequestVerification.RequestTimestampWithinTolerance(skillRequest); bool valid = await RequestVerification.Verify(signature, certUrl, body, GetCertificate); // bool valid = await RequestVerification.Verify(signature, certUrl, body); if (!valid || !isTimestampValid) { log.LogError("Validation failed - RequestVerification failed"); return(false); } else { return(true); } }
/// <summary> /// Validate if all necessary parts for a valid request are available /// and pass them to the RequestsVerification tool /// </summary> /// <param name="context"></param> /// <returns></returns> public async Task Invoke(HttpContext context) { // EnableBuffering so the body can be read without causing issues to the request pipeline context.Request.EnableBuffering(); // Verify SignatureCertChainUrl is present context.Request.Headers.TryGetValue("SignatureCertChainUrl", out var signatureChainUrl); if (string.IsNullOrWhiteSpace(signatureChainUrl)) { context.Response.StatusCode = StatusCodes.Status400BadRequest; return; } Uri certUrl; try { certUrl = new Uri(signatureChainUrl); } catch { context.Response.StatusCode = StatusCodes.Status400BadRequest; return; } // Verify SignatureCertChainUrl is Signature context.Request.Headers.TryGetValue("Signature", out var signature); if (string.IsNullOrWhiteSpace(signature)) { context.Response.StatusCode = StatusCodes.Status400BadRequest; return; } var body = await new StreamReader(context.Request.Body).ReadToEndAsync(); context.Request.Body.Position = 0; if (string.IsNullOrWhiteSpace(body)) { context.Response.StatusCode = StatusCodes.Status400BadRequest; return; } var valid = await RequestVerification.Verify(signature, certUrl, body); if (!valid) { context.Response.StatusCode = StatusCodes.Status400BadRequest; return; } await _next(context); }
public static async Task <bool> ValidateRequestAsync(this SkillRequest skillRequest, HttpRequest request, ILogger log) { // Verifies that the request is indeed coming from Alexa. request.Headers.TryGetValue("SignatureCertChainUrl", out var signatureChainUrl); if (string.IsNullOrWhiteSpace(signatureChainUrl)) { log.LogError("Validation failed. Empty SignatureCertChainUrl header"); return(false); } Uri certUrl; try { certUrl = new Uri(signatureChainUrl); } catch { log.LogError($"Validation failed. SignatureChainUrl not valid: {signatureChainUrl}"); return(false); } request.Headers.TryGetValue("Signature", out var signature); if (string.IsNullOrWhiteSpace(signature)) { log.LogError("Validation failed - Empty Signature header"); return(false); } request.Body.Position = 0; var body = request.Body.ToString(); request.Body.Position = 0; if (string.IsNullOrWhiteSpace(body)) { log.LogError("Validation failed - the JSON is empty"); return(false); } var isTimestampValid = RequestVerification.RequestTimestampWithinTolerance(skillRequest); var isValid = await RequestVerification.Verify(signature, certUrl, body); if (!isValid || !isTimestampValid) { log.LogError("Validation failed - RequestVerification failed"); return(false); } return(true); }
private async Task <bool> ValidateRequest(HttpRequest request, SkillRequest skillRequest) { try { var header = request.Headers; var signature = header["Signature"]; var certUrl = new Uri(header["SignatureCertChainUrl"]); var body = await request.ReadAsStringAsync(); return (RequestVerification.RequestTimestampWithinTolerance(skillRequest) && await RequestVerification.Verify(signature, certUrl, body)); } catch { m_logger.LogError("Validation exception"); return(false); } }
public static async Task EnsureValidAlexaSignatureAsync(this HttpRequest request) { request.EnableRewind(); // Verify SignatureCertChainUrl is present request.Headers.TryGetValue("SignatureCertChainUrl", out var signatureChainUrl); if (string.IsNullOrWhiteSpace(signatureChainUrl)) { throw new InvalidSignatureException(); } Uri certUrl; try { certUrl = new Uri(signatureChainUrl); } catch { throw new InvalidSignatureException(); } // Verify SignatureCertChainUrl is Signature request.Headers.TryGetValue("Signature", out var signature); if (string.IsNullOrWhiteSpace(signature)) { throw new InvalidSignatureException(); } var body = new StreamReader(request.Body).ReadToEnd(); request.Body.Position = 0; if (string.IsNullOrWhiteSpace(body)) { throw new InvalidSignatureException(); } var valid = await RequestVerification.Verify(signature, certUrl, body); if (!valid) { throw new InvalidSignatureException(); } }
private static async Task <bool> ValidateRequestAsync(HttpRequest request, SkillRequest skillRequest) { request.Headers.TryGetValue("SignatureCertChainUrl", out var signatureChainUrl); if (string.IsNullOrWhiteSpace(signatureChainUrl)) { return(false); } Uri certUrl; try { certUrl = new Uri(signatureChainUrl); } catch { return(false); } request.Headers.TryGetValue("Signature", out var signature); if (string.IsNullOrWhiteSpace(signature)) { return(false); } request.Body.Position = 0; var body = await request.ReadAsStringAsync(); request.Body.Position = 0; if (string.IsNullOrWhiteSpace(body)) { return(false); } bool isTimestampValid = RequestVerification.RequestTimestampWithinTolerance(skillRequest); bool valid = await RequestVerification.Verify(signature, certUrl, body); if (!valid || !isTimestampValid) { return(false); } else { return(true); } }
/// <summary> /// Authorize the SkillRequest is coming from Alexa. /// </summary> /// <param name="skillRequest">Incoming SkillRequest from Alexa.</param> /// <param name="requestBody">Full request body from Alexa.</param> /// <param name="signatureChainUrl">Signature Chain Url. This is the SignatureCertChainUrl header value.</param> /// <param name="signature">Signature. This is the Signature header value.</param> /// <returns>True if this is a valid SkillRequest otherwise false.</returns> public virtual async Task <bool> ValidateSkillRequest(CrunchRequest skillRequest, string requestBody, string signatureChainUrl, string signature) { if (skillRequest == null) { _logger.LogError("Validation failed. No incoming skill request."); return(false); } if (string.IsNullOrWhiteSpace(signatureChainUrl)) { _logger.LogError("Validation failed. Empty SignatureCertChainUrl header."); return(false); } Uri certUrl; try { certUrl = new Uri(signatureChainUrl); } catch { _logger.LogError($"Validation failed. SignatureChainUrl not valid: {signatureChainUrl}."); return(false); } if (string.IsNullOrWhiteSpace(signature)) { _logger.LogError("Validation failed. Empty Signature header."); return(false); } if (!RequestVerification.RequestTimestampWithinTolerance(skillRequest)) { _logger.LogError("Validation failed. Request timestamp outside of tolerance."); return(false); } if (!await RequestVerification.Verify(signature, certUrl, requestBody)) { _logger.LogError("Validation failed. Alexa certificate validation failed."); return(false); } return(true); }
public async Task InvokeAsync(HttpContext context) { string bodyStr; using (var reader = new StreamReader(context.Request.Body)) { bodyStr = reader.ReadToEnd(); } if (environment.IsProduction()) { // Verify SignatureCertChainUrl is present context.Request.Headers.TryGetValue("SignatureCertChainUrl", out var signatureChainUrl); if (String.IsNullOrWhiteSpace(signatureChainUrl)) { context.Response.StatusCode = StatusCodes.Status400BadRequest; return; } Uri certUrl; try { certUrl = new Uri(signatureChainUrl); } catch { context.Response.StatusCode = StatusCodes.Status400BadRequest; return; } // Verify SignatureCertChainUrl is Signature context.Request.Headers.TryGetValue("Signature", out var signature); if (String.IsNullOrWhiteSpace(signature)) { context.Response.StatusCode = StatusCodes.Status400BadRequest; return; } if (String.IsNullOrWhiteSpace(bodyStr)) { context.Response.StatusCode = StatusCodes.Status400BadRequest; return; } var valid = await RequestVerification.Verify(signature, certUrl, bodyStr); if (!valid) { context.Response.StatusCode = StatusCodes.Status400BadRequest; return; } } var skillRequest = JsonConvert.DeserializeObject <SkillRequest>(bodyStr); if (skillRequest == null) { context.Response.StatusCode = StatusCodes.Status400BadRequest; return; } var skillResponse = await skillRequestHandler.HandleRequestAsync(skillRequest); await context.Response.WriteAsync(JsonConvert.SerializeObject(skillResponse)); }
protected async Task <ActionResult> CheckBadRequest(SkillRequest skillRequest) { try { if (!RequestVerification.RequestTimestampWithinTolerance(skillRequest)) { LogMessage("Request failed due to TimestampTolerance", SeverityLevel.Error, null); return(BadRequest()); } var sigCertChainUrl = Request.Headers["SignatureCertChainUrl"]; if (String.IsNullOrWhiteSpace(sigCertChainUrl)) { LogMessage("Request failed due to no SignatureCertChainUrl", SeverityLevel.Error, null); return(BadRequest()); } var signature = Request.Headers["Signature"]; if (String.IsNullOrWhiteSpace(signature)) { LogMessage("Request failed due to no Signature", SeverityLevel.Error, null); return(BadRequest()); } var sigCertChainPath = new Uri(sigCertChainUrl); if (!RequestVerification.VerifyCertificateUrl(sigCertChainPath)) { LogMessage($"Request failed due to an invalid Certificate Url ({sigCertChainPath})", SeverityLevel.Error, null); return(BadRequest()); } //var cert = await RequestVerification.GetCertificate(sigCertChainPath); //if (!RequestVerification.VerifyChain(cert)) //{ // LogMessage("Request failed due to invalid Certificate Chain", SeverityLevel.Error, null); // return BadRequest(); //} //Request.Body.Position = 0; var body = await new StreamReader(Request.Body, Encoding.UTF8).ReadToEndAsync(); //Request.Body.Position = 0; if (!await RequestVerification.Verify(signature, sigCertChainPath, body)) { LogMessage($"Request verification failed! (sig: {signature}, sig cert chain: {sigCertChainPath}, request details: {await GetRequestDetails()})", SeverityLevel.Error, null); return(BadRequest()); } } catch (Exception exc) { LogMessage($"Request failed because of unknown error. Request: {await GetRequestDetails()}", SeverityLevel.Error, new Dictionary <string, string>() { { "StackTrace", exc.StackTrace } }); return(BadRequest()); } //Success, let's log the request info temporarily LogMessage($"Successful request: {await GetRequestDetails()}", SeverityLevel.Verbose, "AlexaBaseController", "CheckBadRequest"); return(null); }
/// <summary> /// Validates the request. /// </summary> /// <param name="signature">The Signature value.</param> /// <param name="signatureCertChainUrl">The SignatureCertChainUrl value.</param> /// <param name="body">The body value.</param> /// <returns></returns> private static async Task <bool> IsRequestValid(string signature, Uri signatureCertChainUrl, string body) { return(await RequestVerification.Verify(signature, signatureCertChainUrl, body)); }
public async ValueTask <bool> IsRequestValidAsync(string encodedSignature, Uri signatureCertChainUrl, string request) { return(await RequestVerification.Verify(encodedSignature, signatureCertChainUrl, request)); }