restful api安全设计 – 01

RESTful API简介

  • REST的全称是REpresentational State Transfer,表示 “表述性无状态传输”,无需session,所以每次请求都得带上身份认证信息。
  • rest是基于http协议的,也是无状态的。只是一种架构方式,所以它的安全特性都需我们自己实现,没有现成的。
  • 建议所有的请求都通过https协议发送。
  • RESTful web services 概念的核心就是“资源”, 资源可以用 URI 来表示, 客户端使用 HTTP 协议定义的方法来发送请求到这些 URIs, 当然可能会导致这些被访问的 “资源” 状态的改变。
  • HTTP请求对应关系如下:
    restful_method

身份认证

身份认证包含很多种,有HTTP Basic,HTTP Digest,API KEY,Oauth,JWK等方式,下面简单讲解下:

1.HTTP Basic

  • REST由于是无状态的传输,所以每一次请求都得带上身份认证信息;
  • 身份认证的方式有很多种,第一种便是http basic,这种方式在客户端要求简单,在服务端实现也非常简单,只需简单配置apache等web服务器即可实现,所以对于简单的服务来说还是挺方便的。
  • 但是这种方式安全性较低,就是简单的将用户名和密码base64编码放到header中:

    base64编码前:Basic admin:admin
    base64编码后:Basic YWRtaW46YWRtaW4=
    放到Header中:Authorization:  Basic YWRtaW46YWRtaW4=
    
  • 正是因为是简单的base64编码存储,切记切记在这种方式下一定得注意使用ssl,不然就是裸奔了。

  • 在某些产品中也是基于这种类似方式,只是没有使用apache的basic机制,而是自己写了认证框架,原理还是一样的,在一次请求中base64解码Authorization字段,再和认证信息做校验。

很显然这种方式有问题,认证信息相当于明文传输,另外也没有防暴力破解功能。

2.API KEY

  • API Key就是经过用户身份认证之后服务端给客户端分配一个API Key, 类似: http://example.com/api?key=dfkaj134,
  • 一般的处理流程(一个简单的设计示例)如下:
    client端:
    restful_client_params
    server端:
    restful_server_params

  • 分析:
    client端向服务端注册,服务端把相应的api_key以及security_key给客户端,注意保存不要泄露;
    然后客户端根据api_key,secrity_key,timestrap,rest_uri采用hmacsha256算法得到一个hash值sign,构造途中的url发送给服务端;
    服务端收到该请求后,首先验证api_key是否存在,存在则获取该api_key的security_key;
    接着验证timestrap是否超过时间限制,可依据系统成而定,这样就防止了部分重放攻击(后面还会有更好的解决重放的方案);
    图中的rest_api是从url获取的,为/rest/v1/interface/eth0 ;
    最后计算sign值,完之后和url中的sign值做校验,这样的设计就防止了数据被篡改;
    通过这种API Key的设计方式加了时间戳防止了部分重放,加了校验,防止了数据被篡改,同时避免了传输用户名和密码,当然了也会有一定的开销。

Oauth1.0a或者Oauth2

OAuth协议适用于为外部应用授权访问本站资源的情况。其中的加密机制与HTTP Digest身份认证相比,
安全性更高。使用和配置都比较复杂,这里就不涉及了。

JWT

JWT 是JSON Web Token,用于发送可通过数字签名和认证的东西,它包含一个紧凑的,URL安全的JSON对象,服务端可通过解析该值来验证是否有操作权限,是否过期等安全性检查。
由于其紧凑的特点,可放在url中或者 HTTP Authorization头中,具体的算法就如下图:
restful_JWT

参考:
理解RESTful架构
RESTful API设计指南