Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Validate an Alexa Request within Azure Functions.
using Alexa.NET.Request;
using Microsoft.AspNetCore.Http;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;
namespace AlexaFunctionsApp
{
public static class SkillRequestExtension
{
public static async Task<bool> ValidateRequestAsync(this SkillRequest skillRequest, HttpRequest request, ILogger log)
{
// get signature certification chain url
var signatureCertChainUrl = GetSignatureCertChainUrlFromRequest(request);
if (signatureCertChainUrl == null)
{
log.LogError("Validation failed, because of incorrect SignatureCertChainUrl");
return false;
}
// get signature header
var signature = GetSignatureFromRequest(request);
if (string.IsNullOrWhiteSpace(signature))
{
log.LogError("Validation failed, because of empty signature");
return false;
}
// get body
var body = await GetBodyFromRequestAsync(request);
if (string.IsNullOrWhiteSpace(body))
{
log.LogError("Validation failed, because of empty body");
return false;
}
// validate timestamp
if (!IsTimestampValid(skillRequest))
{
log.LogError("Validation failed, because timestamp is not valid");
return false;
}
// validate signature, signaturecertchainurl and body
if (!await IsRequestValid(signature, signatureCertChainUrl, body))
{
log.LogError("Validation failed, because verification of request failed");
return false;
}
return true;
}
private static Uri GetSignatureCertChainUrlFromRequest(HttpRequest httpRequest)
{
httpRequest.Headers.TryGetValue("SignatureCertChainUrl", out var signatureCertChainUrlAsString);
if (string.IsNullOrWhiteSpace(signatureCertChainUrlAsString))
return null;
Uri signatureCertChainUrl;
try
{
signatureCertChainUrl = new Uri(signatureCertChainUrlAsString);
}
catch
{
return null;
}
return signatureCertChainUrl;
}
private static string GetSignatureFromRequest(HttpRequest httpRequest)
{
httpRequest.Headers.TryGetValue("Signature", out var signature);
return signature;
}
private static async Task<string> GetBodyFromRequestAsync(HttpRequest httpRequest)
{
httpRequest.Body.Position = 0;
var body = await httpRequest.ReadAsStringAsync();
httpRequest.Body.Position = 0;
return body;
}
private static bool IsTimestampValid(SkillRequest skillRequest)
{
return RequestVerification.RequestTimestampWithinTolerance(skillRequest);
}
private static async Task<bool> IsRequestValid(string signature, Uri signatureCertChainUrl, string body)
{
return await RequestVerification.Verify(signature, signatureCertChainUrl, body);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.