REST 是一种软件架构风格。RESTful Api 是基于 HTTP 协议的 Api,是无状态传输。它的核心是将所有的 Api 都理解为一个网络资源。将所有的客户端和服务器的状态转移(动作)封装到 HTTP 请求的 Method  之中.

而本篇文章则主要是讨论 RESTful Api 身份认证安全性设计.

没有绝对的安全,这个话题很深,下文都是自己的一些理解,水平有限,如有勘误,希望大家予以指正。

由于 RESTful Api 是基于 Http 协议的 Api,是无状态传输,所以只要和用户身份有关的请求都会带上身份认证信息。(很多时候客户端事先并不知道某个 api 后期会不会加入身份判断,所以我们一般都会选择每个请求都会带上认证信息,如果有的话。

Http Basic Authentication

Http Basic 是一种比较简单的身份认证方式。在 Http header 中添加键值对 Authorization:  Basic xxx (xxx 是 username:passowrd base64 值)。

例如 username 为 zmk ,password 为 123456,请求则如下

GET /auth/basic/ HTTP/1.1

Host: xxxxx

Authorization: Basic em1rOjEyMzQ1Ng==

而 Base64 的解码是非常方便的,如果不使用 Https ,相当于是帐号密码直接暴露在请求中。

危险性高,实际开发者使用的应该几乎为 0。

顺便提下 DIGEST 认证,和 BASIC 认证相差无几,而且不适合 api 设计,实际又需要两次请求,首次请求,服务器端返回 401,并且带上 nonce 值,然后客户端再利用 username+password+nonce 默认 MD5 之后再请求。对 http 请求的作用是仅仅防止二次请求,对身份认证并没有什么提升。

Access Token

不知道是否应该这么称呼。原理即当客户端登录完毕之后,给客户端返回一个 token,服务器端控制该 token 的有效期,每次请求都带上该值,然后服务器端做验证,退出之后,客户端通知服务端端销毁 token,客户端本地也销毁。但是如果抓包获取到 token,就能任意伪造请求了。

同时 api 接口还存在被第三方开发者或者公司随意利用的风险。也就是说,别人可以非常轻易的就弄出一个你们 app 的复制版,而且还用的你们的所有资源。

危险性高,实际开发估计使用得还不少。

Api Key + Security Key + Sign

下图是我们自己每次请求的身份认证的方式,如有不足,请大家指出。可以说是 JWT 的自定义版吧。

 

这里的认证逻辑即:

用户登录返回一个 api_key 和 security_key;

然后客户端将 security_key 存在客户端;

当要发送请求之前,通过 function2 加密方法,把如图所示的五个值一起加密,得到一个 sign;

发送请求的时候,则将除去 security_key 之外的值,以及 sign 一起发送给服务器端;

服务器端首先验证时间戳是否有效,比如是服务器时间戳 5 分钟之前的请求视为无效;

然后根据 api_key 得到 sercurity_key;

最后验证 sign。

Api key 的作用是什么?(补)

看到有朋友在头条问了这个问题,说下我的实际使用场景:

api key 是用来标识每个不同用户的(也就是说 api key 和用户 id 一一对应的),同时也用来验证security_key 和 sign 的。

比如有 2000 万用户,以 redis 作为数据库,将 api_key 为键,security_key 作为值,api_key 散列分布(比如对末尾位字符的 ASCII 对 20 取模)到 20 个 hashes 里。

当用户请求过来的时候首先根据 api_key 找到对应的 hashes,首先 HEXISTS 检查该 api_key 是否存在,存在则通过 HGET 取出该值,最后一起验证 sign。

是否需要加上时间戳验证?

上面的认证逻辑中加密得到签名的时候,把时间戳加进去是为了在一定程度上屏蔽了一些无效的请求,可以略去,也可以设计的更加严格。如果想防止恶意的 api ddos 攻击,这一步验证肯定是不行的。需要做更多的验证,比如用户验证,ip 验证等。可以参考 github 的 api 的设计。它会在返回的 http 头信息里带上

X-RateLimit-Limit: 5000

X-RateLimit-Remaining: 4999

表示这个接口在某一时间段内,该授权用户调用该接口的最大次数为 5000次,该时间段内还剩余 4999 次。当然,这样的验证加上之后,在代码的执行效率上肯定会有所影响。

是否需要将 request_parameters 也加入到 sign 生成的算法之中?

也不是必须的,仅仅是为了请求的真实性,减少请求的伪造,比如有人抓包拿到 http 请求之后,如果没有验证 sign 这步,那么别人就可以非常简单的修改请求的参数,而请求都会生效。

这里将 request_parameters 也加入到签名之中,就减少了伪造请求的可能性,但是无法杜绝,破坏者可能就非要黑你,又对逆向工程非常熟悉,找到我们加密算法的实现,依然可以未知出合法的签名,所以我们常说,服务器端永远不能相信客户端的请求都是安全的、合法的,需要做验证的都还是不能省略。

同时这(sign算法)也造成了 api 接口调试的成本,api 测试工具必须也得实现那一套算法,或者是设置在开发环境下不做验证。我们在配置开发环境的时候则是 vpn 连测试服务器所在内网,然后进行测试,否则开发环境也存在被人利用的风险。

项目实例 https://github.com/zhoumengkang/netty-restful-server

JWT

JWT (JSON Web Token) 使用流程如下(图片来自官网)

 

其认证机制也是登录,发放密钥给客户端,然后客户端每次发送请求的时候通过 JWT 的算法规则组装 JWT 的Auth Header,服务器端作验证。

web 授权认证的原理万变不离其宗,都是如此。

只不过 JWT 呢,自定了一套认证协议。格式为 Header.Payload.Signature。比如 xxxxx.yyyyy.zzzzz。签名内容是有 Header+Payload+Secret 通过 HMAC SHA256 算法加密而成。

HMACSHA256(

base64UrlEncode(header) + "." +

base64UrlEncode(payload),

secret)

而请求的很多参数键值对都可以放在 Payload 里面。完整讲解请求看官方的介绍 http://jwt.io/introduction/

需要注意的一点,依照 JWT 的协议,只有一个 secret,无法得知该用户是谁,所以在 secret 该值中必须要可以解码出用户的 id。

而我们自定义认证协议的时候 header 感觉就没有必要了,使用什么算法事先定义好即可。所以我们也没选择这种方式而是上面的那种方式。

其他

oauth2.0 则属于第三方认证,不在本篇的讨论范畴之内,可以阅读 http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html

来自:周梦康

链接: http://mengkang.net/620.html

 

RESTful Api 身份认证中的安全性设计探讨的更多相关文章

  1. RESTful Api 身份认证安全性设计

    REST是一种软件架构风格.RESTful Api 是基于 HTTP 协议的 Api,是无状态传输.它的核心是将所有的 Api 都理解为一个网络资源.将所有的客户端和服务器的状态转移(动作)封装到 H ...

  2. 关于RESTFUL API 安全认证方式的一些总结

    常用认证方式 在之前的文章REST API 安全设计指南与使用 AngularJS & NodeJS 实现基于 token 的认证应用两篇文章中,[译]web权限验证方法说明中也详细介绍,一般 ...

  3. 关于 RESTFUL API 安全认证方式的一些总结

    常用认证方式 在之前的文章REST API 安全设计指南与使用 AngularJS & NodeJS 实现基于 token 的认证应用两篇文章中,[译]web权限验证方法说明中也详细介绍,一般 ...

  4. 基于Node的PetShop,RESTful API以及认证

    前篇 - 基本认证,用户名密码 后篇 - OAuth2 认证 由于宠物店的业务发展需要,我们需要一种更加便捷的方式来管理日益增多的宠物和客户.最好的方法就是开发一个APP,我可以用这个APP来添加.更 ...

  5. 关于ASP.Net Core Web及API身份认证的解决方案

    6月15日,在端午节前的最后一个工作日,想起有段日子没有写过文章了,倒有些荒疏了.今借夏日蒸蒸之气,偷得浮生半日悠闲.闲话就说到这里吧,提前祝大家端午愉快(屈原听了该不高兴了:))!.NetCore自 ...

  6. RESTFUL API 安全认证方式

    一般基于REST API 安全设计常用方式有: HTTP Basic Basic admin:admin Basic YWRtaW46YWRtaW4= Authorization: Basic YWR ...

  7. 如何设计好的RESTful API之安全性

    保证RESTful API的安全性,主要包括三大方面: a) 对客户端做身份认证 b) 对敏感的数据做加密,并且防止篡改 c) 身份认证之后的授权 1.对客户端做身份认证,有几种常见的做法: 1)在请 ...

  8. 虚拟研讨会:如何设计好的RESTful API?

    http://www.infoq.com/cn/articles/how-to-design-a-good-restful-api/ REST架构风格最初由Roy T. Fielding(HTTP/1 ...

  9. 虚拟研讨会:如何设计好的RESTful API(转)

    原文:虚拟研讨会:如何设计好的RESTful API? REST架构风格最初由Roy T. Fielding(HTTP/1.1协议专家组负责人)在其2000年的博士学位论文中提出.HTTP就是该架构风 ...

随机推荐

  1. node.js BootStrap安装

    最近想用Bootstrap开发项目,以便使用其丰富的资源: 捯饬了一下nodejs的安装和配置:windows下弄起来还是比较狗屎的,两三天下班时间才弄好: http://xiaoyaojones.b ...

  2. 查看jquery绑定的事件函数

    作为技术狂热分子的职业本能,看到一个技术产品的功能,总会忍不住想知道它是怎么被实现的.比如我每每看到别人网站一个很炫的界面或者很酷的功能,就忍不住打开了浏览器的控制台... 好,不扯远,说说当你想看到 ...

  3. linux服务之smtp

    实现这个协议的软件太多,有sendmail,postfix等.不像snmp,基本上是net-snmp一统天下, yum install nc nc用来取代telnet 这里我们希望让大家知道网络协议中 ...

  4. 反射矩阵(reflection matrix)推导

    设平面为(nx,ny,nz,d),则以此平面为镜面的列主序反射矩阵如下: 推导如下: 一,平面的表示: 如图所示,过点p,法向量为n的平面,可表示为: np+d=0 其中d为平面到原点的有向距离.如果 ...

  5. sql查询重复记录并取对应最小值

    原表(aa): id   a                      b 1    22                    456 2    22                    256 ...

  6. Hive(六):HQL DDL

    HQL语法基于 SqlLine(http://sqlline.sourceforge.net/),DDL主要包含数据库.函数.视图的创建.修改.删除,参考资料:(https://cwiki.apach ...

  7. 安装Android sdk 4.4(19)出现问题的解决方案

    刚更新了Android sdk 19,但是出现以下两个问题,浪费我2个小时的时间,现在将我遇到的问题和解决方法总结如下: 问题1:打开eclipse点更新后,出现This Android SDK re ...

  8. C#时间日期格式大全

    C#时间/日期格式大全,C#时间/日期函数大全 有时候我们要对时间进行转换,达到不同的显示效果 默认格式为:2016-7-1 14:33:34 如果要换成成201607,07-2016,2016-7- ...

  9. 05文件与IO

    这节主要学习了read.write.lseek.目录访问(opendir.readdir.closedir)这几个系统调用及其简单的应用. 一旦有了与一个打开文件描述相连的文件描述符,只要该文件是用O ...

  10. 【linux】压缩和解压缩

    .gz格式 压缩gzip: gzip只能压缩文件,且压缩后文件消失,不能压缩目录. [root@andon tmp]# ls ml orbit-gdm pulse-2sLvu7UbjUYf pulse ...