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

选择合适的安全协议

行业标准认证协议有助于减少就保护你的 API 所做的相关投入。也能够使用自己定义安全协议。但仅限于一些非常特殊的场景。

下面是几个主要协议的长处和缺点的概述。

基本认证 w/TLS

基本认证是三个通用协议(基本、Oauth 1.0a、Oauth2)里边实现起来最简单的一个。主要是由于时间方面,它的实现不须要额外的库。

实现基本认证所须要的全部东西往往都已经包括于你使用的标准框架或者语言库里了。

基本认证的问题是,它太“基本”了。它仅提供了通用协议的最主要的安全选项。

它没有提供使用这样的协议的高级选项,所以你也就仅仅能够发送使用 Base64 加密过的username和password了。

在没有 TLS(原名 SSL)加密的情况下永远不要使用基本协议,由于username和password的组合非常easy就被破解掉。

Oauth 1.0a

Oauth 1.0a 是三个通用协议里边最安全的一个。Oauth1 是一个被广泛使用的、久经考验的、安全的、基于签名的协议。该协议使用一套加密签名机制,对令牌密钥、随机数以及其它基于请求的信息使用进行签名。Oauth1 最大的长处是你永远不直接通过网络传输令牌密钥。这也就全然消除了某些人通过在传输过程中得到password的可能性。

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,等等)都提供client库以让你的用户毫不费力地使用这些协议的时候,你才干够使用自己定义协议。

否则你的 API 会被人无视。
我们选择了什么协议?在 Stormpath,我们用的就是一个自己定义授权协议。

它和 OAuth1 非常相似。但它提供了非常多增强功能(比方,不同于 OAuth1,Stormpath 的方案对请求体签名,因此通过计算签名能够保证请求体没有被篡改)。可是相同,这一算法仅仅对于使用实现了该算法的 SDK 的client实用。对于其它不使用我们 SDK 的客户我们所提供的还是其它通用协议。

为什么使用 API 密钥。而不是username/password

我们使用的还有一个技术是用生成的 API 密钥替代传统的username/password方式。

这一决定见博客《使用 API 密钥的六个主要原因(以及怎样使用!)》,但它对于 API 安全相同非常重要,因此这里我们再对其简单反复一遍:

API 密钥/password通常是非常难推測的一长串的随机字符。

username/password则通常比較短,并且使用经常使用词,通常是不安全的,非常easy遭到暴力破解或字典攻击。

重置password的问题

password会经常被重置。假设你使用password作为你的 API 授权方案的一部分,每次password重置之后 API 訪问将会失败。

速度

最佳实践告诉我们将password加密后再保存在数据库中来限制潜在的数据泄露。但这却添加了每一个请求做用户认证时的所带来的系统负载。独一无二的 API 密钥认证略过了这个哈希校验的步骤因此能够使得你的调用得到提速。

假设你就password存储想了解很多其它,參考博客《password存放的安全方式》。

保存你的 API 密钥

在 Stormpath 我们鼓舞将 API 密钥/password保存在一个(应用)全部者仅仅读的文件里。密钥/password对下载之后就被保存到本地文件系统。然后改动该文件全部权,仅仅有(应用的)用户能够读取。这样就限制了 SDK 使用密钥的时候所带来的泄露问题。

ID 的使用方法

为了减少你的 id 所带来的安全隐患,你应该把它们设置为不透明的并且全球唯一的。

不要使用 "1234"。使用 "f6cd3459f9a39c9784b3e328f05be0f7"。禁用有序数列不仅能够帮助我们防止黑客对下一个数字进行"推測",还能防止 id 值的争用问题。在 Stormpath,在 UUID 生成的时候我们使用的是 "Url62"。使用了 62 "url 安全" 的字符串基本上是由一个全球独一无二的字节数组编码生成的。

这样能够让我们把 id 安全地使用在 URL 中。而不必担心编码问题。

会话和 URL

避免为我们的 REST API 创建会话已经成了 Stormpath 的一个非常好的实践,并帮我们提高了 API server性能。

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

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

  1. Web API CSRF保护实现

    Web API CSRF保护实现 这次自己实现了类似jQuery中ajax调用的方法,并且针对RESTFul进行了改造和集成,实现的A2D AJAX接口如下: $.ajax.RESTFulGetCol ...

  2. ASP.NET Core 中基于 API Key 对私有 Web API 进行保护

    这两天遇到一个应用场景,需要对内网调用的部分 web api 进行安全保护,只允许请求头账户包含指定 key 的客户端进行调用.在网上找到一篇英文博文 ASP.NET Core - Protect y ...

  3. A2D JS框架 - Web API CSRF保护实现

    这次自己实现了类似jQuery中ajax调用的方法,并且针对RESTFul进行了改造和集成,实现的A2D AJAX接口如下: $.ajax.RESTFulGetCollection("/ap ...

  4. 利用Laravel 搭建oauth2 API接口 附 Unauthenticated 解决办法

    利用Laravel 搭建oauth2 API接口 要求 laravel 5.4以上 安装 $ composer require laravel/passport 在配置文件 config/app.ph ...

  5. Identity Server 4 - Hybrid Flow - 保护API资源

    这个系列文章介绍的是Identity Server 4 的 Hybrid Flow, 前两篇文章介绍了如何保护MVC客户端, 本文介绍如何保护API资源. 保护MVC客户端的文章: https://w ...

  6. 如何使用人工智能保护API的安全

    数字转型是基于一种可驱动新的操作模型的API,提供对业务逻辑.应用程序和数据的直接访问.虽然这种访问对于员工,合作伙伴和客户来说非常方便,但它也使API成为黑客和恶意网络的攻击目标.随着越来越多的攻击 ...

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

    开篇先扯几句题外话,许多朋友都问我怎么不写防啊,我确实有点犹豫.hackers总是想象如果自己是开发者会怎么写,然后才能找到入手点.同理,开发者们也要想象自己是hackers会怎么做,才能采取相应的防 ...

  8. DELPHI下API简述(1800个API)

    DELPHI下API简述 http://zero.cnbct.org/show.asp?id=144 auxGetDevCaps API 获取附属设备容量 auxGetNumDevs API 返回附属 ...

  9. .NET Core IdentityServer4实战 第一章-入门与API添加客户端凭据

    内容:本文带大家使用IdentityServer4进行对API授权保护的基本策略 作者:zara(张子浩) 欢迎分享,但需在文章鲜明处留下原文地址. 本文将要讲述如何使用IdentityServer4 ...

随机推荐

  1. hdu 2242 无向图/求用桥一分为二后使俩个bcc点权值和之差最小并输出 /缩点+2次新图dfs

    题意如标题所述, 先无向图缩点,统计出每个bcc权,建新图,然后一遍dfs生成树,标记出每个点(新图)以及其子孙的权值之和.这样之后就可以dfs2来枚举边(原图的桥),更新最小即可. 调试了半天!原来 ...

  2. 参数化1--jmeter参数化数据(_csvread函数、用户自定义变量等)

    以下是转载内容,仔细看过后,觉得用得最多的应该是csvread函数.用户自定义变量以及CSV DATA CONFIG控制器这几个,但是做练习之后,在结果树和聚合报告中怎么查看执行结果是个问题,没找到对 ...

  3. NULL的学问

    在数据库中存在一种特殊的值:NULL(空值).一个字段如果没有被赋值,那么它的值就是NULL,NULL并不代表没有值而是表示值未知.员工信息表中存储着身份证号.姓名.年龄等信息,其中某条记录中年龄字段 ...

  4. POJ 1054 The Troublesome Frog 枚举

    这个题分类是dp,想了一会没有想出来,就去看别人题解了.发现别人题解全是暴力枚举= =.复杂度超过 N^2,但可能是剪枝的作用,没有超时. 思路:将所有点按坐标由小到大排序.两两枚举点p1,p2,并判 ...

  5. Python--Day2/Day3/Day4(运算符、数据类型及内建函数)

    一.昨日内容回顾 Python种类:CPython(Python).JPython.IronPython.PyPy 编码: Unicode.UTF-8.GBK while循环 if...elif... ...

  6. DB11 TCP数据协议拆包接收主要方法

    北京地标(DB11) 据接收器. /// <summary> /// DB11协议拆包器 /// </summary> public class SplictProtocol ...

  7. Windows API 教程(七) hook 钩子监听

    茵蒂克丝 如何创建一个窗口 手动创建窗口的流程 实际代码 安装钩子 (Install hook) 钩子简介 SetWindowsHookEx 函数 设置监听[键盘]消息 设置监听[鼠标]消息 如何创建 ...

  8. spring batch的使用和定时器Quart的使用

    Spring Batch是一个基于Spring的企业级批处理框架,它通过配合定时器Quartz来轻易实现大批量的数据读取或插入,并且全程自动化,无需人员管理. 在使用spring batch之前,得对 ...

  9. 从头认识java-14.2 进一步了解数组

    这一章节我们来全面了解一下数组. 1.数组在初始化之前.我们不能使用他的引用来做不论什么事情. package com.ray.ch14; public class Test { public sta ...

  10. springMVC --配置具体与注讲解明

    <?xml version="1.0" encoding="UTF-8"? > <beans xmlns="http://www.s ...