首页 新闻 搜索 专区 学院

WebApi过滤器无法收到post请求中body的数据?

0
悬赏园豆:10 [待解决问题]

过滤器代码如下:

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;就是用来获取提交的数据。可是总是为""

麻烦各位大神给看看哪里出现问题啦

P了个F的主页 P了个F | 初学一级 | 园豆:191
提问于:2018-04-27 11:12
< >
分享
所有回答(1)
0

由于我使用了console host方式部署。而且配置的也有问题,所以不能获取到post的值。修改为httpselfhostserver

P了个F | 园豆:191 (初学一级) | 2018-04-27 17:51
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册