我想验证 slack APIS 命令和交互式端点,我按照此处的文档 https://api.slack.com/authentication/verifying-requests-from-slackand 尝试将其转换为 C#...
我想验证 slack APIS 命令和交互式端点,我按照此处的文档 https://api.slack.com/authentication/verifying-requests-from-slack 并尝试将其转换为 C# 代码和此函数
private bool VerifySlackRequest(HttpRequest request, IHeaderDictionary headers,
StringValues slackSignatureHeader)
{
string SlackSigningSecret = ConfigurationHelper.SlackSigningSecret;
DateTime timestamp = DateTimeOffset.FromUnixTimeSeconds(timestampUnix).UtcDateTime;
DateTime currentTimestamp = DateTime.UtcNow;
if (Math.Abs((currentTimestamp - timestamp).TotalSeconds) > 60 * 5)
{
// The request timestamp is more than five minutes from local time.
// It could be a replay attack, so let's ignore it.
return false;
}
// Get the request body as a URL-encoded string
string requestBody = string.Join("&", request.Form.Select(kvp => $"{kvp.Key}={kvp.Value}"));
var encoding = new UTF8Encoding();
using (var hmac = new HMACSHA256(encoding.GetBytes(SlackSigningSecret)))
{
var hash = hmac.ComputeHash(encoding.GetBytes($"v0:{headers["X-Slack-Request-Timestamp"]}:{requestBody}"));
var hashString = $"v0={BitConverter.ToString(hash).Replace("-", "").ToLower(CultureInfo.InvariantCulture)}";
if (hashString.Equals(slackSignatureHeader)) return true;
else return false;
}
}
以下是我调用函数的方式
bool isValidRequest = VerifySlackRequest(Request, Request.Headers, slackSignatureHeader);
if (!isValidRequest)
{
return Unauthorized("Invalid request signature");
}
我确认了 SlackSigningSecret,但 slackSignatureHeader 和 hashString 始终不匹配
问题是我如何获取请求主体
string requestBody = string.Join("&", request.Form.Select(kvp => $"{kvp.Key}={kvp.Value}"));
当我用缓冲得到它时它工作正常
string rawRequestBody = string.Empty;
request.EnableBuffering();
using (var reader = new StreamReader(request.Body))
{
rawRequestBody = await reader.ReadToEndAsync();
Request.Body.Position = 0;
}
如果你有同样的问题并且 rawRequestBody 总是空的,请在你的 Startup.cs 中添加此内容
app.Use((context, next) =>
{
context.Request.EnableBuffering();
return next();
});
我写了一篇关于它的中篇文章,如果有人尝试 Slack 签名验证,你可以 在这里