web api越来越火,因为它的跨平台,因为它的简单,因为它支持xml,json等流行的数据协议,我们在开发基于面向服务的API时,有个问题一直在困扰着我们,那就是数据的安全,请求的安全,一般所说的安全也无非就是请求的防篡改和请求的防复用,例如,你向API发一个查询用户账户的请求,在这个过程中,你可能要传递用户ID,用户所在项目ID等,而现在拦截工具如此盛行,很容易就可以把它的请求拦截,然后篡改,再转发,这样你的API就是不安全的,而对于订单,账户模块这种糟糕的API设计更是致命的,可能引起的损失是不可预计的,是灾难性的,拍拍脑子想想就知道,你向项目提现10元,我把请求拦截把10改成100000,那么这个将是一个灾难!
防篡改
一般使用的方式就是把参数拼接,加上双方约定的“密钥”,加上你的当前项目AppKey,做一次MD5加密,这个过程生成的字符串我们一般称为密文,而对应的可见参数我们叫明文,其中明文和密文用于网络传输,而密钥存储在本地和服务器,不能进行传输!
防复用
一般请求,被重复的使用,也是正常的,就上面的方式进行加密,就无法解决防复用的问题,这时我们需要在客户端和服务端分别生成UTC的时间戳,这个UTC是防止你的客户端与服务端不在同一个时区,呵呵,然后把时间戳timestamp拼在密文里就可以了,至于防复用的有效性,我们可以自定义,当然大叔定义的是秒,即同一秒内,请求可以重复发送。
大叔API安全结构图
aaarticlea/png;base64,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" alt="" />
web api核心安全校验代码片断
代码供大家参考和学习,正式的项目可以根据自己公司的需要去设计
/// <summary>
/// 功能:api数据安全性验证
/// 校验方式:ciphertext=md5(form键的值拼接+timestamp+passkey),服务端用接收到的表单数据与时间戳和自己的passkey进行md5生成,最后比较值是否一致
/// passkey为私钥,不用于网络传递,你可以将它与appKey进行关联,appKey用来传递,服务器根据appKey去数据库里取对应的passkey然后进行比较
/// 功能:请求唯一性,防伪造性
/// timestamp:UTC时间戳,不用于网络传递,在客户端调用服务器时,服务器也生成yyyyMMddhhmmss的时间戳,然后进行计算,看是否过期
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public class ApiValidateFilter : ActionFilterAttribute
{
public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
{
#region 初始化
var context = (HttpContextBase)actionContext.Request.Properties["MS_HttpContext"];//获取传统context
var request = context.Request;//定义传统request对象
var paramStr = new StringBuilder();
var coll = new NameValueCollection();
if (request.HttpMethod.ToLower() == "get")
coll = request.QueryString;
else
coll = request.Form;
#endregion #region 解析XML配置文件
var config = CacheConfigFile.ConfigFactory.Instance.GetConfig<ApiValidateModelConfig>().ApiValidateModelList.FirstOrDefault(i => i.AppKey == coll["AppKey"]);
if (config == null)
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden)
{
Content = new StringContent("AppKey不是合并的,请先去组织生成有效的Key", Encoding.GetEncoding("UTF-8"))
};
base.OnActionExecuting(actionContext);
}
if (config.ExpireDate < DateTime.Now)
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden)
{
Content = new StringContent("AppKey不是合并的,密钥已过期", Encoding.GetEncoding("UTF-8"))
};
base.OnActionExecuting(actionContext);
}
#endregion #region 验证算法
var keys = new List<string>();
foreach (string param in coll.Keys)
{
if (!string.IsNullOrEmpty(param))
{
keys.Add(param.ToLower());
} }
keys.Sort();
foreach (string p in keys)
{
if (p != "ciphertext")
{
if (!string.IsNullOrEmpty(coll[p]))
{
paramStr.Append(coll[p]);
} }
}
paramStr.Append(DateTime.Now.ToUniversalTime().ToString("yyyyMMddHHmmss"));
paramStr.Append(config.PassKey);
#endregion if (Lind.DDD.Utils.Encryptor.Utility.EncryptString(paramStr.ToString(), Lind.DDD.Utils.Encryptor.Utility.EncryptorType.MD5)
!= request["cipherText"])
{ actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden)
{
Content = new StringContent("验证失败,请求非法", Encoding.GetEncoding("UTF-8"))
};
} base.OnActionExecuting(actionContext);
}
}
在上的配置项大叔把它存储到的XML里,使用的是大叔自己封装的XML缓存组件CacheConfigFile,文件第一次访问会加载到内存,下次使用直接从内存返回,而当文件修改后,文件的最后更新时间发生变化,这时缓存过期,在生产缓存时,还是采用了单例模式,
这个在大叔框架里经常被看到,呵呵。
aaarticlea/png;base64,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" alt="" />