过滤器代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using Newtonsoft.Json;
using NLog;
using OpenApiSelfHost.Tools;
namespace OpenApiSelfHost
{
public class PartnerIdentityAttribute : ActionFilterAttribute
{
private readonly ILogger logger = LogManager.GetCurrentClassLogger();
private const string X_Ca_Key = "X-Ca-Proxy-Signature-Secret-Key";
private const string X_Ca_Proxy_Signature = "X-Ca-Proxy-Signature";
private const string X_Ca_Proxy_Signature_Headers = "X-Ca-Proxy-Signature-Headers";
private const string X_Ca_Error_Message = "X-Ca-Error-Message";
public override void OnActionExecuting(HttpActionContext actionContext)
{
try
{
var headers = actionContext.Request.Headers;
if (!headers.Contains(X_Ca_Key) || !headers.Contains(X_Ca_Proxy_Signature) ||
!headers.Contains(X_Ca_Proxy_Signature_Headers))
{
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Forbidden,
"Signature info error, forbidden");
return;
}
var appKey = actionContext.Request.Headers.GetValues(X_Ca_Key).ElementAt(0);
var secret = PartnerAuthHelper.GetAppSecret(appKey);
string METHOD = actionContext.Request.Method.Method.ToUpper();
string Content_MD5 = "";
if (METHOD == "POST" || METHOD == "PUT")
{
byte[] content = actionContext.Request.Content.ReadAsByteArrayAsync().Result;
MD5 md5 = MD5.Create();
byte[] hs = md5.ComputeHash(content);
Content_MD5 = Convert.ToBase64String(hs);
}
string Headers = "";
string[] headersToSign = actionContext.Request.Headers.GetValues(X_Ca_Proxy_Signature_Headers).ToArray();
string[] headerSignKeys = headersToSign[0].Split(',');
foreach (var key in headerSignKeys)
{
string values = actionContext.Request.Headers.GetValues(key).ElementAt(0);
Headers += $"{key}:{values}\n";
}
string url = actionContext.Request.RequestUri.AbsolutePath;
SortedDictionary<string, string> dict = new SortedDictionary<string, string>();
var queryInfo = actionContext.Request.RequestUri.ParseQueryString();
foreach (var item in queryInfo.AllKeys)
{
dict.Add(item, queryInfo[item]);
}
if (actionContext.Request.Content.IsFormData())
{
var formData = actionContext.Request.Content.ReadAsFormDataAsync().Result;
foreach (var item in formData.AllKeys)
{
dict.Add(item, formData[item]);
}
}
if (dict.Any())
{
url += "?";
foreach (var item in dict)
{
url += $"{item.Key}={item.Value}&";
}
}
url = url.TrimEnd('&');
string stringToSign = $"{METHOD}\n{Content_MD5}\n{Headers}{url}";
var sign = ComputeSign(stringToSign, secret);
string encryptSign = actionContext.Request.Headers.GetValues(X_Ca_Proxy_Signature).ElementAt(0);
if (sign != encryptSign)
{
logger.Debug($"request sign debug info - request headers: {JsonConvert.SerializeObject(actionContext.Request.Headers)}");
logger.Debug($"request sign debug info - request url: {url}");
logger.Debug($"request sign debug info - request query info: {JsonConvert.SerializeObject(queryInfo)}");
logger.Debug($"request sign debug info - source string to sign: {stringToSign.Replace('\n', '|')}");
logger.Debug($"request sign debug info - encrypt sign: {encryptSign}");
logger.Debug($"request sign debug info - stringto sign: {sign}");
actionContext.Response.Headers.Add(X_Ca_Error_Message, sign);
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Forbidden,
"Invalid signature, forbidden");
}
base.OnActionExecuting(actionContext);
}
catch (Exception e)
{
logger.Error(e);
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Forbidden,
"Signature error, forbidden");
}
}
private string ComputeSign(string stringToSign, string secret)
{
byte[] keyBytes = Encoding.UTF8.GetBytes(secret);
byte[] stringToSignBytes = Encoding.UTF8.GetBytes(stringToSign);
using (var hmacsha256 = new HMACSHA256(keyBytes))
{
byte[] hashmessage = hmacsha256.ComputeHash(stringToSignBytes);
var sign = Convert.ToBase64String(hashmessage);
return sign;
}
}
}
}
其中的actionContext.Request.Content.ReadAsByteArrayAsync().Result;就是用来获取提交的数据。可是总是为""
麻烦各位大神给看看哪里出现问题啦
由于我使用了console host方式部署。而且配置的也有问题,所以不能获取到post的值。修改为httpselfhostserver