using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Routing;
using Web.APIs.Integration.Common;
namespace Web.APIs.Integration.WebApi
{
public class SignAttribute : AuthorizeAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
DateTime dtBegin = DateTime.Now;
bool flag = false;
string errorMsg = string.Empty;
string exceptionMsg = string.Empty;
Dictionary<string, string> dictionary = new Dictionary<string, string>();
try
{
if (ConfigurationManager.AppSettings["Debug"].ToUpper() == "TRUE")
{
flag = true;
}
else
{
IHttpRouteData routeData = actionContext.Request.GetRouteData();
if (routeData != null && routeData.Values != null)
{
foreach (string current in routeData.Values.Keys)
{
dictionary.Add(current, routeData.Values[current].ToString());
}
}
if (actionContext.Request.Method == HttpMethod.Post)
{
HttpContextBase httpContextBase = (HttpContextBase)actionContext.Request.Properties["MS_HttpContext"];
if (httpContextBase.Request.InputStream != null)
{
Stream inputStream = httpContextBase.Request.InputStream;
inputStream.Position = 0L;
StreamReader streamReader = new StreamReader(inputStream);
string text = streamReader.ReadToEnd();
if (text != string.Empty)
{
text = text.Replace("\"", "");
string decryptKey = ConfigurationManager.AppSettings["DESKey"];
string text2 = DES.Decrypt(text, decryptKey);
Dictionary<string, string> dictionary2 = JsonConvert.DeserializeObject<Dictionary<string, string>>(text2);
if (dictionary2 != null)
{
foreach (string current2 in dictionary2.Keys)
{
dictionary.Add(current2, dictionary2[current2]);
}
}
}
}
}
flag = this.Vertify(dictionary, dtBegin, out errorMsg, out exceptionMsg);
}
}
catch (Exception ex)
{
errorMsg = "验签失败";
exceptionMsg = "验签时发生异常。原因:" + ex.Message;
}
if (flag)
{
this.IsAuthorized(actionContext);
}
else
{
Task.Factory.StartNew(delegate
{
var objResult = new
{
Msg = errorMsg,
Exp = exceptionMsg
};
Error.Write(actionContext, exceptionMsg, objResult, dtBegin);
});
BaseResult baseResult = new BaseResult();
baseResult.Result = flag;
baseResult.ReturnMsg = errorMsg;
HttpResponseMessage httpResponseMessage = new HttpResponseMessage(HttpStatusCode.Unauthorized);
httpResponseMessage.Content = new StringContent(JsonConvert.SerializeObject(baseResult));
actionContext.Response = httpResponseMessage;
this.HandleUnauthorizedRequest(actionContext);
}
}
protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
{
}
private bool Vertify(Dictionary<string, string> dicParams, DateTime dtBegin, out string errorMsg, out string exceptionMsg)
{
bool result = true;
errorMsg = string.Empty;
exceptionMsg = string.Empty;
if (dicParams == null || dicParams.Count == 0)
{
result = false;
errorMsg = "无请求参数";
exceptionMsg = "无请求参数";
}
else
{
SortedDictionary<string, string> sortedDictionary = new SortedDictionary<string, string>();
string text = string.Empty;
int num = 0;
foreach (string current in dicParams.Keys)
{
if (current.ToLower() != "sign")
{
sortedDictionary.Add(current, dicParams[current]);
if (current.ToLower() == "timestamp")
{
num = Convert.ToInt32(dicParams[current]);
}
}
else
{
text = dicParams[current];
}
}
bool flag = false;
if (num > 0)
{
try
{
DateTime time = this.GetTime(num);
int num2 = Convert.ToInt32(ConfigurationManager.AppSettings["TimeStampExpire"]);
if (num2 > 0)
{
if (Math.Abs((time - dtBegin).TotalMinutes) <= (double)num2)
{
flag = true;
}
}
else
{
flag = true;
}
}
catch (Exception ex)
{
exceptionMsg = "转换时间戳格式时出错,原因:" + ex.Message;
}
}
if (!flag)
{
result = false;
errorMsg = "请求时间过期";
}
else
{
string empty = string.Empty;
string secret = ConfigurationManager.AppSettings["MD5KEY"];
string sign = ToponeMD5.GetSign(sortedDictionary, secret, ref empty);
if (sign != text)
{
result = false;
errorMsg = "请求的签名不正确";
exceptionMsg = string.Format("签名错误!请求的签名为:{0}, 本地生成的签名为:{1},本地接受的签名明文为:{2}", text, sign, empty);
}
}
}
return result;
}
private Dictionary<string, string> ConvertToDictionary(string input)
{
Dictionary<string, string> dictionary = new Dictionary<string, string>();
if (input.IndexOf("&") > 0)
{
string[] array = input.Split("&".ToCharArray());
for (int i = 0; i < array.Length; i++)
{
if (array[i] != string.Empty)
{
string[] array2 = array[i].Split("=".ToCharArray());
dictionary.Add(array2[0], HttpUtility.UrlDecode(array2[1]));
}
}
}
return dictionary;
}
private DateTime GetTime(int timeStamp)
{
DateTime dateTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
long ticks = long.Parse(timeStamp + "0000000");
TimeSpan value = new TimeSpan(ticks);
return dateTime.Add(value);
}
}
}