对你的 REST API 进行保护的正确办法

设计好一个漂亮的 REST + JSON API 之后,如何对你的 API 进行保护?在 Stormpath,我们花了 18 个月来寻找最佳实践,将其一一实践于 Stormpath API 中并分析其效果。本文将阐述如何保护 REST API。

选择合适的安全协议

行业标准认证协议有助于减少就保护你的 API 所做的相关投入。也可以使用自定义安全协议,但仅限于一些非常特殊的场景。以下是几个主要协议的优点和缺点的概述。

基本认证 w/TLS

基本认证是三个通用协议(基本、Oauth 1.0a、Oauth2)里边实现起来最简单的一个,主要是因为时间方面,它的实现不需要额外的库。实现基本认证所需要的所有东西往往都已经包含于你使用的标准框架或者语言库里了。基本认证的问题是,它太“基本”了,它仅提供了通用协议的最基本的安全选项。它没有提供使用这种协议的高级选项,所以你也就只能够发送使用 Base64 加密过的用户名和密码了。在没有 TLS(原名 SSL)加密的情况下永远不要使用基本协议,因为用户名和密码的组合很容易就被破解掉。

Oauth 1.0a

Oauth 1.0a 是三个通用协议里边最安全的一个。Oauth1 是一个被广泛使用的、久经考验的、安全的、基于签名的协议。该协议使用一套加密签名机制,对令牌密钥、随机数以及其他基于请求的信息使用进行签名。Oauth1 最大的优点是你永远不直接通过网络传输令牌密钥,这也就完全消除了某些人通过在传输过程中得到密码的可能性。Oauth1 是三个协议里唯一一个没有 SSL 就可以安全使用的协议(尽管如果传输数据很敏感你仍然会使用 SSL)。但是这种级别的安全是有代价的:对于签名的生成和校验会是一个复杂的过程。你必须使用具有一系列严格步骤的哈希算法。尽管如此,这一复杂性对你来讲已不再是一个问题,因为每个主流的编程语言都具备一个库来替你处理这些了。

Oauth2

Oauth2 听起来像是 Oauth1 的演化版本,但事实上它是一个完全不同的试图降低身份验证复杂性的协议。Oauth2 的当前版本已经移除了签名,这也就意味着你不再需要使用加密算法来创建、生成以及校验签名了。现在其所有的加密处理都是 TLS,而且是必需的。Oauth2 也不再像 Oauth1 那样有一堆的库,因此将这一协议集成进你的 API 可能更具有挑战性。去年(译者注:本文原文写于 2013 年),Oauth2 标准的第一作者和编辑离职。由于规范委员会的这一不稳定性,也由于 Oauth2 的默认设置的安全性低于 Oauth1(没有了数字签名也就意味着你无法验证数据内容在传输前和传输后的完整性),因此对于敏感数据的应用我们相比 Oauth2 我们更推荐 Oauth1Oauth2 可以应用于更低敏感性的场景,比如一些社交网络。

自定义

应该避免使用自定义授权协议,除非你确实、确实知道你在做什么并且对于数字签名加密的纷繁芜杂也完全明白。大多数机构对此都没有专业意见,因此我们建议 OAuth1.0a 作为一个可靠的替补方案。
如果你执意选择走这条存在潜在危险的道路,还有另一个理由来劝你回头:因为它是自定义的,因此除了你之外再没有其他人能够轻松使用它了。只有在你愿意给你的 REST API 调用者(Java,Ruby,PHP,Python,等等)提供客户端库以让你的用户毫不费力地使用这些协议的时候,你猜可以使用自定义协议。否则你的 API 会被人无视。
我们选择了什么协议?在 Stormpath,我们用的就是一个自定义授权协议。它和 OAuth1 很类似,但它提供了很多增强功能(比如,不同于 OAuth1,Stormpath 的方案对请求体签名,因此通过计算签名可以保证请求体没有被篡改)。但是同样,这一算法仅仅对于使用实现了该算法的 SDK 的客户端有用。对于其他不使用我们 SDK 的客户我们所提供的还是其他通用协议。

为什么使用 API 密钥,而不是用户名/密码

我们使用的另一个技术是用生成的 API 密钥替代传统的用户名/密码方式。这一决定见博客《使用 API 密钥的六个主要原因(以及如何使用!)》,但它对于 API 安全同样非常重要,因此这里我们再对其简单重复一遍:

API 密钥/密码通常是很难猜测的一长串的随机字符。用户名/密码则通常比较短,而且使用常用词,一般是不安全的,而且很容易遭到暴力破解或字典攻击。

重置密码的问题

密码会经常被重置。如果你使用密码作为你的 API 授权方案的一部分,每次密码重置之后 API 访问将会失败。

速度

最佳实践告诉我们将密码加密后再保存在数据库中来限制潜在的数据泄露。这增加了每个请求做用户认证时的负载。独一无二的 API 密钥认证略过了这个哈希校验的步骤因此使得你的调用得到提速。如果你就密码存储想了解更多,参考博客《密码存放的安全方式》。

保存你的 API 密钥

在 Stormpath 我们鼓励将 API 密钥/密码保存在一个所有者只读的文件中。密钥/密码对下载之后就被保存到本地文件系统。然后修改该文件所有权,只有(应用的)用户可以读取。这样限制 SDK 使用密钥的时候带来的泄露。

ID 的用法

为了减少你的 id 的安全责任,你应该把它们设置为不透明的且全球唯一的。不要使用 "1234",使用 "f6cd3459f9a39c9784b3e328f05be0f7"。禁用有序数列能够帮助防止黑客对下一个数字进行"猜测",还能防止 id 值的争用问题。在 Stormpath,在 UUID 生成的时候我们使用的是 "Url62"。使用了 62 "url 安全" 的字符串基本上是由一个全球独一无二的字节数组编码生成的。这样可以让我们把 id 安全地使用在 URL 中,而不必担心编码问题。

会话和 URL

避免为我们的 REST API 创建会话已经成了 Stormpath 的一个很好的实践,并帮我们提高了 API 服务器性能。除了避免会话集群(数据库,Memcached,等等)的开销,你可以添加额外的机器到你的 API 集群以满足你增加的用户群需要。
在你实现一个认证方案的时候(比如"谁可以看到什么"的规则),尽量不要依赖于一个 URL 来保护你的数据或者功能。URL 会随着时间发生变化,所以使用资源本身或其内容作为你进行访问控制决策的出发点。
Stormpath CTO Les 也有一个很棒的的关于 REST 安全的视频
原文链接:https://stormpath.com/blog/secure-your-rest-api-right-way/

时间: 2024-08-15 20:18:49

对你的 REST API 进行保护的正确办法的相关文章

区块链技术是版权保护的“正确打开方式”

21世纪是互联网的时代,也是知识经济时代.在互联网发展成熟的现阶段,网络成为了众人获取信息.知识.消遣的主要渠道.越来越多的人开始进入新媒体,网络的创作者人数也日益增加,同时网络上也带来了大量的网络版权问题.今天墨者安全就给大家说一下版权保护方面的事情. 为什么说区块链技术是版权保护的正确打开方式呢? 首先是因为区块链独有的特性,有着去中心化.高安全性.不可篡改.公开透明的特性.通过区块链技术可以完整的记录作品和创作者的详细信息,并全部公开:所有的节点都可以共同记录,共同维护:并且盖上不可篡改的

DELPHI下API简述(1800个API)

DELPHI下API简述 http://zero.cnbct.org/show.asp?id=144 auxGetDevCaps API 获取附属设备容量 auxGetNumDevs API 返回附属设备数量 auxGetVolume API 获取当前卷设置 auxOutMessage API 向输出设备发送消息 auxSetVolume API 设置附属设备卷 AbortDoc API 终止一项打印作业 AbortPath API 终止或取消DC中的一切路径 AbortPrinter API

(转)iOS安全 对本地文件的保护

开篇先扯几句题外话,许多朋友都问我怎么不写防啊,我确实有点犹豫.hackers总是想象如果自己是开发者会怎么写,然后才能找到入手点.同理,开发者们也要想象自己是hackers会怎么做,才能采取相应的防御措施.然后,就是一场递归的博弈.拿越狱检测这件事来说,起初大家只需判断有无安装Cydia就好了,hackers们说好,那我就不安装Cydia也可以动手脚.开发者们又说,那你一定得用的上MobileSubstrate,bash,ssh吧,我去检测手机有没有安装这些工具.可是又有什么用呢?你判断什么我

REST API (from IBM)

REST 本身是设计风格而不是标准.REST 谈论一件非常重要的事,如何正确地使用 Web标准,例如,HTTP 和 URI.想要了解 REST 最好的方式就是思索与了解 Web 及其工作方式.如果你设计的应用程序能符合 REST 原则 (REST principles),这些符合 REST 原则的 REST 服务可称为 "RESTful web service" 也称 "RESTful Web API"."-ful" 字尾强调它们的设计完全符合

[转]10个有关RESTful API良好设计的最佳实践

Web API已经在最近几年变成重要的话题,一个干净的API设计对于后端系统是非常重要的. 通常我们为Web API使用RESTful设计,REST概念分离了API结构和逻辑资源,通过Http方法GET, DELETE, POST 和 PUT来操作资源. 下面是进行RESTful Web API十个最佳实践,能为你提供一个良好的API设计风格. 1.使用名词而不是动词 Resource资源 GET读 POST创建 PUT修改 DELETE /cars 返回 cars集合 创建新的资源 批量更新c

Web API项目中使用Area对业务进行分类管理

在之前开发的很多Web API项目中,为了方便以及快速开发,往往把整个Web API的控制器放在基目录的Controllers目录中,但随着业务越来越复杂,这样Controllers目录中的文件就增加很快,难以管理,而且如果有不同业务模块有重复的控制器名的话,还需要尽量避免.引入Area的作用就是把控制器按照不同的业务模块进行区分,方便管理,而且控制器名称可以重名. 1.Web API项目引入Area进行分类 Area在项目中可以称之为区域,每个Area代表应用程序的不同功能模块,Area 使每

DB表的关系及EF中Fluent API的使用

现在使用多数的数据库是关系型数据库,那么表与表之间的关系就会显得尤其重要,对于数据的CRUD处理和以后数据的分析有很大的好处.下面是对于数据库中对表关系的理解以及在EF中使用Fluent API来创建这种关系的例子. 数据库中实体之间的联系 书中语录:在现实世界中,事务内部以及事务之间是有联系的,这些联系在计算机里面叫做实体之间的联系和实体内部的联系,内部的联系就是组成实体属性之间的联系,而实体之间的联系可以分为三类.(1:1, 1:n, n:n) 一:一对一联系(1:1) A实体集中每一个实体

Android多媒体--MediaCodec 中文API文档

*由于工作需要,需要利用MediaCodec实现Playback及Transcode等功能,故在学习过程中翻译了Google官方的MediaCodec API文档,由于作者水平限制,文中难免有错误和不恰当之处,望批评指正. *转载请注明出处:http://www.cnblogs.com/roger-yu/ MediaCodec public final class MediaCodec extends Object Java.lang.Object → android.media.MediaCo

Android应用开发中如何使用隐藏API(转)

一开始需要说明的是,Google之所以要将一些API隐藏(指加上@hide标记的public类.方法或常量)是有原因的.其中很大的原因就是Android系统本身还在不断的进化发展中.从1.0.1.1到现在即将问世的Android 2.3.4. 这些隐藏的API本身可能是不稳定的,所以,使用隐藏API,意味着程序更差的兼容性. 如果要我给出建议的话,最好还是不要使用隐藏的API.不过有时为了实现Android应用某些特殊的功能或者效果,隐藏的API往往能发挥意想不到的作用.这些API具体能做些什么