WebAPI 安全性 使用TOKEN+签名验证(下)

  //根据请求类型拼接参数

            NameValueCollection form = HttpContext.Current.Request.QueryString;

            string data = string.Empty;

            switch (method)

            {

                case "POST":

                    Stream stream = HttpContext.Current.Request.InputStream;

                    string responseJson = string.Empty;

                    StreamReader streamReader = new StreamReader(stream);

                    data = streamReader.ReadToEnd();

                    break;

                case "GET":

                    //第一步:取出所有get参数

                    IDictionary<string, string> parameters = new Dictionary<string, string>();

                    for (int f = 0; f < form.Count; f++)

                    {

                        string key = form.Keys[f];

                        parameters.Add(key, form[key]);

                    }

                    // 第二步:把字典按Key的字母顺序排序

                    IDictionary<string, string> sortedParams = new SortedDictionary<string, string>(parameters);

                    IEnumerator<KeyValuePair<string, string>> dem = sortedParams.GetEnumerator();

                    // 第三步:把所有参数名和参数值串在一起

                    StringBuilder query = new StringBuilder();

                    while (dem.MoveNext())

                    {

                        string key = dem.Current.Key;

                        string value = dem.Current.Value;

                        if (!string.IsNullOrEmpty(key))

                        {

                            query.Append(key).Append(value);

                        }

                    }

                    data = query.ToString();

                    break;

                default:

                    resultMsg = new ResultMsg();

                    resultMsg.StatusCode = (int)StatusCodeEnum.HttpMehtodError;

                    resultMsg.Info = StatusCodeEnum.HttpMehtodError.GetEnumText();

                    resultMsg.Data = "";

                    actionContext.Response = HttpResponseExtension.toJson(JsonConvert.SerializeObject(resultMsg));

                    base.OnActionExecuting(actionContext);

                    return;

            }

            

            bool result = SignExtension.Validate(timestamp, nonce, id, signtoken,data, signature);

            if (!result)

            {

                resultMsg = new ResultMsg();

                resultMsg.StatusCode = (int)StatusCodeEnum.HttpRequestError;

                resultMsg.Info = StatusCodeEnum.HttpRequestError.GetEnumText();

                resultMsg.Data = "";

                actionContext.Response = HttpResponseExtension.toJson(JsonConvert.SerializeObject(resultMsg));

                base.OnActionExecuting(actionContext);

                return;

            }

            else

            {

                base.OnActionExecuting(actionContext);

            }

        }

        public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)

        {

            base.OnActionExecuted(actionExecutedContext);

        }

    }

 

然后我们进行测试,检验api请求的合法性

 

Get请求:

 

1.获取产品数据,传递参数id=1,name="wahaha"  ,完整请求为http://localhost:14826/api/product/getproduct?id=1&name=wahaha

 

 

2.请求头添加timespan,staffid,nonce,signature字段

 

 

3.如图当data里面的值为id1namewahaha的时候请求头中的signature和服务器端计算出来的result的值是完全一样的,当我将data修改为id1namewahaha1之后,服务器端计算出来的签名result和请求头中提交的signature就不相同了,就表示为不合法的请求了

 

 

4.不合法的请求就会被识别为请求参数已被修改

 

  合法的请求则会返回对应的商品信息

 

post请求:

 

1.post对象序列化为json字符串后提交到后台,后台返回相应产品信息

 

 

2.后台获取请求的参数信息

 

 

3.判断签名是否成功,第一次请求签名参数signature和服务器端计算result完全相同, 然后当把请求参数中count的数量从10改成100之后服务器端计算的result和请求签名参数signature不同,所以请求不合法,是非法请求,同理如果其他任何参数被修改最后计算的结果都会和签名参数不同,请求同样识别为不合法请求

 

 

总结:

 

通过上面的案例,我们可以看出,安全的关键在于参与签名的TOKEN,整个过程中TOKEN是不参与通信的,所以只要保证TOKEN不泄露,请求就不会被伪造。

 

然后我们通过timestamp时间戳用来验证请求是否过期,这样就算被人拿走完整的请求链接也是无效的。

 

Sign签名的方式能够在一定程度上防止信息被篡改和伪造,保障通信的安全

源码地址:https://github.com/13138899620/TokenSign

posted on 2016-10-22 10:49  張暁磊  阅读(555)  评论(0编辑  收藏  举报