博主喝口茶,一毛也是爱

收缩

Asp.Net MVC使用过滤器验证请求参数合法性

2153 人阅读
分类:

Asp.Net MVC接收参数的时候如何对请求参数进行统一验证

可以通过自定义过滤器统一处理

当验证失败直接返回,验证通过继续执行控制器方法


添加 using System.Web.Mvc

public class BasicApiAuthorize : AuthorizeAttribute
{
    /// <summary>
    /// 接口加密签名
    /// </summary>
    public string SecretKey = "Project2022!@#.*.";

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        string postData = "";
        var requestStream = filterContext.HttpContext.Request.InputStream;
        //using (var steam = requestStream)
        //{
        byte[] bytes = new byte[requestStream.Length];
        requestStream.Read(bytes, 0, bytes.Length);
        //设置当前流的位置为流的开始
        requestStream.Seek(0, SeekOrigin.Begin);

        //将bytes转换为流(生成新的Stream,防止读取一次就被清空数据了)
        Stream newStream = new MemoryStream(bytes);
        using (newStream)
        {
            if (newStream.Length > 0)
            {
                var byts = new byte[newStream.Length];
                newStream.Read(byts, 0, (int)byts.Length);
                postData = Encoding.UTF8.GetString(byts);
            }
        }

        if (string.IsNullOrEmpty(postData))
        {
            //直接返回请求,请求终止
            filterContext.Result = getResultContent(400, "请求参数为空");
            return;
        }
        var dataInfo = JsonConvert.DeserializeObject<ApiBasicCommon>(postData);
        if (dataInfo == null
            || dataInfo.timestamp <= 0
            || string.IsNullOrEmpty(dataInfo.sign))
        {
            filterContext.Result = getResultContent(400, "请求参数无效");
            return;
        }

        //验证时间戳是否合法(时间戳转换)
        var timeDate = convertIntDatetime(dataInfo.timestamp);
        var diffNow = (DateTime.Now - timeDate).TotalSeconds;
        if (diffNow < -60 || diffNow > 60)
        {
            filterContext.Result = getResultContent(400, "时间戳无效");
            return;
        }
        //验证签名是否有效,这里简单使用 md5加密,加密方法自己找下
        var _sign = StringHelper.ToMD5($"{dataInfo.timestamp.ToString()}{SecretKey}");
        if (_sign.ToLower() != dataInfo.sign.ToLower())
        {
            filterContext.Result = getResultContent(400, "签名无效");
            return;
        }

        //如果执行到这里说明参数验证通过,后续会执行控制器方法
    }

    private ActionResult getResultContent(int error_code = 0, string message = "ok")
    {
        var actionResult = new ContentResult();
        var result = new
        {
            error_code = error_code,
            message = message
        };
        actionResult.ContentEncoding = Encoding.GetEncoding("UTF-8");
        actionResult.ContentType = "application/json";
        actionResult.Content = JsonConvert.SerializeObject(result);

        return actionResult;
    }

    private DateTime convertIntDatetime(double utc)
    {
        System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
        startTime = startTime.AddMilliseconds(utc);
   
        return startTime;
    }

}
public class ApiBasicCommon
{
    /// <summary>
    /// 时间戳
    /// </summary>
    public long timestamp { get; set; }
    /// <summary>
    /// 签名
    /// </summary>
    public string sign { get; set; }
}

控制器上添加特性

[BasicApiAuthorize]
public class AppApiController : Controller
{
    [HttpPost]
    public ActionResult AddOrder(AppOrderInfoRequest request)
    {
        return Json(new { code = 200, message = "成功" });
    }
}

这样所有访问AddOrder方法都会先进入BasicApiAuthorize验证,验证通过后才会进入AddOrder方法


和博主交个朋友吧
    发布篇幅
    • 文章总数:0
    • 原创:0
    • 转载:0
    • 译文:0
    文章分类
      文章存档
      阅读排行