设计好一个漂亮的 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/。

对你的 REST API 进行保护的正确办法相关推荐

  1. 使用 Play Integrity API 来保护您的应用和游戏

    在 Android 平台上有丰富的应用和游戏,为用户带来了很多绝佳的使用体验.其中大部分的用户会按照应用或游戏所设计的体验路线享受其带来的乐趣.但还是有一些用户来者不善,他们会通过作弊.恶意篡改.欺诈 ...

  2. 通过托管代码和 Windows Vista 智能卡 API 来保护您的数据

    智能存储 这篇文章基于 Windows Vista 的预发布版而撰写.其中包含的信息可能会有所变动. 本文讨论: Windows 智能卡编程基础 示例智能卡应用程序的实现方法 编写实现智能卡功能的托管 ...

  3. API战略中台的正确落地方式:构建高效的“API管理平台”

    白山云科技 "一个组织的API战略应当是该组织数字化战略的重要支撑,并在其中占有相当大的比例." --Gartner分析师Paolo Malinverno, Mark O'Neil ...

  4. 查看Android API文档的正确方式

    AS中简单查看API 在AS中我们可以简单查看函数或类的API,选中我们想要查看的函数或类的代码,按快捷键 Ctrl+Q,AS就会弹出一个简单说明的窗口: 但一般我们的是这样: 那是因为AS去访问Go ...

  5. 微信与服务器通讯失败,linux服务器微擎提示couldn’t resolve host api.weixin.qq.com解决办法...

    微信通信错误是不少 couldn't resolve host api.weixin.qq.com错误的分享,老贴: 操作步骤: 1.服务器命令行中测试能否解释成功 因为php程序调用的是curl,所 ...

  6. Lua 报错 PANIC: unprotected error in call to Lua API (no calling environment) 解决办法

    问题表现 lua_State *L = lua_open(); /* opens Lua */ luaopen_base(L); /* opens the basic library */ luaop ...

  7. Quest v31 Passthrough API无法透视的问题解决办法

    洪流学堂,让你快人几步.你好,我是大智. 最近Oculus Quest v31 SDK更新了可以支持透视功能了(实验版),但是一顿操作以后发现怎么搞都是黑屏.今天大智终于知道如何解决了. 除了按照Oc ...

  8. 新加用户被保护的解决办法

    chattr -i /etc/passwd chattr -i /etc/passwd- chattr -i /etc/shadow chattr -i /etc/group chattr -i /e ...

  9. java鉴权_一个开箱即用的高效认证鉴权框架,专注于restful api的认证鉴权动态保护...

    作者:tomsun28 来源:SegmentFault 思否 写在开头 看了看这个专栏的最近一篇文章已经是两年前了,时间过得好快.应该是出学校后时间就很快了.两年前因为用shiro后,自己就按着想法开 ...

最新文章

  1. ajax传值的url,JQuery ajax url传值与data传值的区别
  2. linux-命令替换-通配符-重定向-管道
  3. java regex
  4. Visual C++下对匿名管道的编程实现
  5. Codeforces 140D - New Year Contest
  6. 第五天总结 运算符 职业化 运算符优先级 职业精神
  7. linux 内核 工作队列,Linux内核新旧工作队列机制的剖析和比较
  8. 解决:Request header field Content-Type is not allowed by Access-Control-Allow-Headers
  9. linux内核input子系统解析,ARM Linux内核Input输入子系统浅解
  10. 【English】十六、时间相关
  11. 串口调试助手fx2n_PLC串口调试助手详细讲解(结合实操)
  12. 互联网行业的HR怎么看待30岁以上的基础岗位求职者
  13. python里创建数据库表Column常用参数总结
  14. [授权发表]程序执行的那一刹那
  15. Qt设计一个给图像打掩膜的界面
  16. javaweb课程设计:基于websocket的网络聊天室(所有的资源和代码还有详细步骤我都会提供)
  17. ZZULIOJ-1001,植树问题(Java)
  18. PCIe TLP的格式
  19. IBMV7000存储电源模块PSU报错“Power Supply Fault type 2“
  20. 龙芯版UOS 自带浏览器无法使用flash在线播放视频

热门文章

  1. 用不服输的态度去生活,用委屈撑开长大
  2. xp系统支持64g内存_WindowsXP支持最多64G内存的工具震撼登场
  3. 小程序毕业设计-课程签到小程序 在线课程打开小程序 课程考勤小程序 扫码签到小程序【附远程调试+讲解+文档】
  4. aspx文件的Page指令参数
  5. 计算机学情问卷调查报告,小学生学情调查问卷及调查分析报告.doc
  6. 【转】宋代的“福利国家”气象
  7. python jieba模块基本命令讲解
  8. SpringBoot自问世以来,一直有一个响亮的口号“约定优于配置“
  9. 数据结构——小白入门篇
  10. Flume中的HDFS Sink配置参数说明