Web API系列(二)接口安全和参数校验
以前简单介绍过web api 的设计,但是还是有很多朋友问我,如何合理的设计和实现web api。比如,接口安全,异常处理,统一数据返回等问题。所以有必要系统的总结总结 web api 的设计和实现。由于前面已经介绍过web api 的参数和返回格式的设计,《Web API系列(一)设计经验与总结》。这次,就来讲讲接口安全。
由于Web API是基于互联网的应用,因此安全性要远比在本地访问数据库的要严格的多,一般通用的做法,是采用几步来保证接口和数据安全:
1.首先一个是基于CA证书的HTTPS进行数据传输,防止数据被窃听;
2.然后是采用参数加密签名方式传递,对传递的参数,增加一个加密签名,在服务器端验证签名内容,防止被篡改;
3.最后是对一般的接口访问,都需要使用用户身份的token进行校验,只要检查通过才允许访问数据。
Web API接口的访问方式,大概可以分为几类:
1)使用用户名密码。这种方式比较简单,可以有效识别用户的身份(如包括用户信息、密码、或者相关的接口权限等等)。验证成功后,返回相关的数据。
2)使用安全签名。这种方式提交的数据,URL连接的签名参数是经过安全一定规则的加密的,服务器收到数据后也经过同样规则的安全加密,确认数据没有被中途篡改后,再进行数据修改处理。因此我们可以为不同客户端,如Web/APP/Winfrom等不同接入方式指定不同的加密秘钥,但是秘钥是双方约定的,并不在网络连接上传输,连接传输的一般是这个接入的AppID,服务器通过这个AppID来进行签名参数的加密对比。目前微信后台的回调处理机制,应该就是这么处理的。
3)公开的接口调用,不需要传入用户令牌、或者对参数进行加密签名的,这种接口一般较少,只是提供一些很常规的数据显示而已。

web api 安全校验
使用用户名密码的实现方式比较简单,这里就不说明如何实现了。就讲一讲安全签名的实现。由于Web API的调用,都是一种无状态的调用方式,所有的接口请求,都要带安全签名。

web api核心安全校验代码片断:
public class QueryData
{
public QueryData()
{ } public QueryData(IEnumerable<KeyValuePair<string, string>> paramList)
{
// TODO: Complete member initialization
try
{
if (paramList == null)
{
throw new Exception("请求参数为空!");
} foreach (var param in paramList)
{
m_values[param.Key] = param.Value; //
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
} //采用排序的Dictionary的好处是方便对数据包进行签名,不用再签名之前再做一次排序
private SortedDictionary<string, object> m_values = new SortedDictionary<string, object>(); /**
* 设置某个字段的值
* @param key 字段名
* @param value 字段值
*/
public void SetValue(string key, object value)
{
m_values[key] = value;
} /**
* 根据字段名获取某个字段的值
* @param key 字段名
* @return key对应的字段值
*/
public object GetValue(string key)
{
object o = null;
m_values.TryGetValue(key, out o);
return o;
} /**
* 判断某个字段是否已设置
* @param key 字段名
* @return 若字段key已被设置,则返回true,否则返回false
*/
public bool IsSet(string key)
{
object o = null;
m_values.TryGetValue(key, out o);
if (null != o)
return true;
else
return false;
} public string ToUrl()
{
string buff = "";
foreach (KeyValuePair<string, object> pair in m_values)
{
if (pair.Value == null)
{
throw new Exception("内部含有值为null的字段!");
} if (pair.Key != "sign" && pair.Value.ToString() != "")
{
buff += pair.Key + "=" + pair.Value + "&";
}
}
buff = buff.Trim('&');
return buff;
} public string MakeSign(string appKey = "test")
{
//转url格式
string str = ToUrl();
//在string后加入API KEY
str += "&key=" + appKey;
//MD5加密
var md5 = MD5.Create();
var bs = md5.ComputeHash(Encoding.UTF8.GetBytes(str));
var sb = new StringBuilder();
foreach (byte b in bs)
{
sb.Append(b.ToString("x2"));
}
//所有字符转为大写
return sb.ToString().ToUpper();
} public bool CheckSign()
{
//如果没有设置签名,则跳过检测
if (!IsSet("sign"))
{
throw new Exception("签名存在但不合法!");
}
//如果设置了签名但是签名为空,则抛异常
else if (GetValue("sign") == null || GetValue("sign").ToString() == "")
{
throw new Exception("签名存在但不合法!");
} //获取接收到的签名
string return_sign = GetValue("sign").ToString(); //在本地计算新的签名
string cal_sign = MakeSign(); if (cal_sign == return_sign)
{
return true;
}
return false;
}
}
代码供大家参考和学习,正式的项目可以根据自己公司的需要去设计,后续也会开源相关的完整项目源代码。
Web API系列(二)接口安全和参数校验的更多相关文章
- Redis总结(五)缓存雪崩和缓存穿透等问题 Web API系列(三)统一异常处理 C#总结(一)AutoResetEvent的使用介绍(用AutoResetEvent实现同步) C#总结(二)事件Event 介绍总结 C#总结(三)DataGridView增加全选列 Web API系列(二)接口安全和参数校验 RabbitMQ学习系列(六): RabbitMQ 高可用集群
Redis总结(五)缓存雪崩和缓存穿透等问题 前面讲过一些redis 缓存的使用和数据持久化.感兴趣的朋友可以看看之前的文章,http://www.cnblogs.com/zhangweizhon ...
- Web API系列(三)统一异常处理
前面讲了webapi的安全验证和参数安全,不清楚的朋友,可以看看前面的文章,<Web API系列(二)接口安全和参数校验>,本文主要介绍Web API异常结果的处理.作为内部或者是对外提供 ...
- Web Api 与 Andriod 接口对接开发经验
最近一直急着在负责弄Asp.Net Web Api 与 Andriod 接口开发的对接工作! 刚听说要用Asp.Net Web Api去跟 Andriod 那端做接口对接工作,自己也是第一次接触Web ...
- Asp.Net Web Api 与 Andriod 接口对接开发经验,给小伙伴分享一下!
最近一直急着在负责弄Asp.Net Web Api 与 Andriod 接口开发的对接工作! 刚听说要用Asp.Net Web Api去跟 Andriod 那端做接口对接工作,自己也是第一次接触Web ...
- Asp.Net Web Api 与 Andriod 接口对接开发
Asp.Net Web Api 与 Andriod 接口对接开发经验,给小伙伴分享一下! 最近一直急着在负责弄Asp.Net Web Api 与 Andriod 接口开发的对接工作! 刚听说要用A ...
- Asp.Net Web API(二)
创建一个Web API项目 第一步,创建以下项目 当然,你也可以创建一个Web API项目,利用 Web API模板,Web API模板使用 ASP.Net MVC提供API的帮助页. 添加Model ...
- Web API系列之三 基本功能实现
Web API系列之二讲解了如何搭建一个WebApi的基架,本文主要在其基础之上实现基本的功能.下面开始逐步操作: 一.配置WebApi的路由-用于配置外部如何访问内部资源的url的规则 1.添加Gl ...
- ASP.NET Web API系列教程目录
ASP.NET Web API系列教程目录 Introduction:What's This New Web API?引子:新的Web API是什么? Chapter 1: Getting Start ...
- 【转】ASP.NET WEB API系列教程
from: 西瓜小强 http://www.cnblogs.com/risk/category/406988.html ASP.NET Web API教程(六) 安全与身份认证 摘要: 在实际的项目应 ...
随机推荐
- get和post的区别
http://localhost:8080/shopc/check.do?username=zhangsan&pwd=123456 http://localhost:8080/shopc/ch ...
- ORACLE 博客文章目录(2015-05-27更新)
从接触ORACLE到深入学习,已有好几年了,虽然写的博客不多,质量也参差不齐,但是,它却是成长的历程的点点滴滴的一个见证,见证了我在这条路上的寻寻觅觅,朝圣的心路历程,现在将ORACLE方面的博客整理 ...
- MySQL同步常见问题解答(自己的小心得)
前几天刚刚注册了博客园,我想写一些技巧性的教程,今天给大家分享一个MySQL同步常见问题解答. Q:如果主服务器正在运行并且不想停止主服务器,怎样配置一个从服务器? A:有多种方法.如果你在某时间点做 ...
- Oracle学习笔记四 SQL命令(二):SQL操作语言类别
SQL分为下列语言类别 1.数据定义语言(DDL) Create.Alter.Drop 2.数据操纵语言(DML) Insert.Select.Delete.Update 3.事务控制语言(TCL) ...
- python-pickle模块使用实例
以下代码主要实现的是用户登录,注册,密码验证,账户锁定,重置和修改密码等功能 import pickle #第一次运行请去掉下面一段代码的注释 ''' users_db = open("us ...
- chkconfig
chkconfig的级别: 0:关机 1:单用户模式 2:无网络支持的多用户模式 3:有网络支持的多用户模式 4:保留,未使用 5:有网络支持有X-Windows(图形界面)支持的多用户模式 6:重新 ...
- python ldap
# -*- coding: UTF-8 -*- import ldap, ConfigParser, os from ldap import modlist LDAP_HOST = "myd ...
- python爬虫学习(6) —— 神器 Requests
Requests 是使用 Apache2 Licensed 许可证的 HTTP 库.用 Python 编写,真正的为人类着想. Python 标准库中的 urllib2 模块提供了你所需要的大多数 H ...
- Re 模块
re模块提供方法如compile, search, findall, match和其他的方法.这些函数是使用REGEX语法建立了一个模式来处理文本的. 第一个方法:search. 一个基本的搜索工作原 ...
- Mysql5.5升级到5.7后MySQLdb不能正常使用的问题解决
ubuntu系统 报错信息1 Type "help", "copyright", "credits" or "license&qu ...