Web App (angular)、iOS 和 Android 可以使用的安全 RESTful API

Posted

技术标签:

【中文标题】Web App (angular)、iOS 和 Android 可以使用的安全 RESTful API【英文标题】:Secured RESTful API that can be used by Web App (angular), iOS and Android 【发布时间】:2013-04-30 07:27:15 【问题描述】:

我必须制定一个计划来开发一个 RESTful API (Python/Flask),我们未来的网络应用程序 (Angularjs) 和移动应用程序 (ios/android) 可以使用它。

我研究了三天,遇到了几种情况: 使用 HTTPS 是在以下方法之上保持安全的一种方法。但是 https 速度较慢,这可能意味着我们需要更快、更昂贵的服务器。

    使用 Basic-Http-Auth 并通过网络以纯格式(但为 https)发送用户名/密码,以处理对 API 的每个请求。 使用 Digest-Auth,它是密码的哈希值,并且跟踪将是自动的 这将适用于 Web 应用程序,但是我无法确认 iPhone 和 Android 是否会本机支持此功能。如果他们这样做,那可能是一个简单的解决方案! 使用自定义 http 标头,在成功验证后,我将在 http 标头中发送自定义 Auth 字符串。但是我必须确保为用户提出的每个请求发送此身份验证代码。这使得它与 1) 完全一样,不同之处在于不使用普通密码,并且身份验证代码可以过期而没有任何风险。同样有问题的是身份验证代码的跟踪,它不再像 2) 中那样自动化 使用 OAuth 是一个选项。但是设置起来相当困难。如果没有更好的方法,也许这是唯一的方法? 如great article 中所述,保护像 Amazon S3 这样的 API。简而言之,他说服务器和客户端都知道私钥,他们将使用它来散列通信。这就像黑帮握手一样,如果他知道黑帮握手,您只会信任送货员。再往下走,有人问:

如何在纯 html5 应用程序中保持私钥“安全”?

你完全正确;在纯 HTML5 (JS/CSS/HTML) 应用程序中, 没有保护密钥。你会做所有的沟通 HTTPS 在这种情况下你不需要密钥,因为你可以安全地 使用标准 API_KEY 或其他友好的方式识别客户端 标识符,而不需要 HMAC 或 HMAC 的复杂性。

因此,换句话说,首先将这种方法用于网络应用程序甚至没有意义。老实说,我也不明白这应该如何在移动设备上工作。用户下载我们的应用程序,我如何将私钥从 iphone 发送到服务器?一旦我转移它,它就会被泄露。

我研究得越多,我就越犹豫不决。

我希望能请教一些以前做过这方面的专业人士,并可以分享他们的经验。非常感谢

【问题讨论】:

我正在努力解决同样的问题。身份验证似乎是 REST 房间里的大象…… jbandi,这个问题更多的是关于保护流量而不是身份验证(如果我没看错的话)。如果您有关于如何在 RESTful/Web API 中处理身份验证的具体问题,我不介意回答。布局后,身份验证/会话管理选项与传统 Web 应用程序相同。 【参考方案1】:

您似乎将两个不同的概念混淆/合并在一起。我们开始讨论加密流量 (HTTPS),然后我们开始讨论管理经过身份验证的会话的不同方法。在安全应用程序中,这些不是相互排斥的任务。似乎还可能存在对会话管理如何影响身份验证的误解。在此基础上,我将提供有关 Web 应用程序/Web api 会话管理、身份验证和加密的入门知识。

简介

会话管理

HTTP 事务默认是无状态的。 HTTP 没有指定任何方法让您的应用程序知道 HTTP 请求已从特定用户发送(无论是否经过身份验证)。

对于强大的 Web 应用程序,这是不可接受的。我们需要一种方法来关联跨多个请求发出的请求和数据。为此,在对服务器的初始请求时,需要为用户分配一个“会话”。通常会话具有某种发送给客户端的唯一 ID。客户端随每个请求发送该会话 ID,服务器使用每个请求中发送的会话 ID 为用户正确准备响应。

重要的是要记住,“会话 ID”可以被称为许多其他东西。其中一些示例是:会话令牌、令牌等。为了保持一致性,我将在此响应的其余部分使用“会话 ID”。

来自客户端的每个 HTTP 请求都需要包含会话 ID;这可以通过多种方式完成。流行的例子是:

    它可以存储在 cookie 中 - 当前域的 cookie 会在每次请求时自动发送。 可以在 URL 上发送 - 每个请求都可以在 URL 上发送会话 ID,不建议因为会话 ID 将保留在客户端历史记录中 它可以作为 HTTP 标头发送 - 每个请求都需要指定标头

大多数 Web 应用程序框架都使用 cookie。但是,依赖 javascript 和单页设计的应用程序可能会选择使用 HTTP 标头/将其存储在服务器可观察到的其他位置。

请务必记住,通知客户端其会话 ID 的 HTTP 响应以及包含会话 ID 的客户端请求是完全纯文本且 100% 不安全的。为了解决这个问题,所有 HTTP 流量都需要加密;这就是 HTTPS 的用武之地。

还需要指出的是,我们还没有讨论将会话链接到系统中的特定用户。会话管理只是将数据与访问我们系统的特定客户端相关联。客户端可以处于已验证和未验证状态,但在这两种状态下它们通常都有一个会话。

身份验证

身份验证是我们将会话链接到系统中的特定用户的地方。这通常由用户提供凭据的登录过程处理,这些凭据经过验证,然后我们将会话链接到系统中的特定用户记录。

用户又通过访问控制列表和访问控制条目(ACL 和 ACE)与细粒度访问控制的权限相关联。这通常被称为“授权”。大多数系统总是同时具有身份验证和授权。在一些简单的系统中,所有经过身份验证的用户都是平等的,在这种情况下,您将无法通过简单身份验证获得授权。有关此问题的更多信息超出了此问题的范围,但请考虑阅读有关 ACE/ACL 的信息。

可以用不同的方式将特定会话标记为代表经过身份验证的用户。

    他们的会话数据存储在服务器端,可以存储他们的用户 ID/其他一些标志,表明该用户已作为特定用户进行身份验证 另一个用户令牌可以像会话 id 一样发送到客户端(通过未加密的 HTTP 与发送未加密的会话 id 一样不安全)

任何一个选项都可以。这通常取决于您所使用的技术以及它们默认提供的功能。

客户端通常会启动身份验证过程。这可以通过将凭据发送到特定 URL(例如 yoursite.com/api/login)来完成。但是,如果我们想成为“RESTful”,我们通常会通过某个名词引用资源并执行“创建”操作。这可以通过要求将凭据发布到 yoursite.com/api/authenticatedSession/ 来完成。想法是创建一个经过身份验证的会话。大多数站点只是将凭据发布到 /api/login 等。这与“真正的”或“纯粹的”RESTful 理想背道而驰,但大多数人认为这是一个更简单的概念,而不是将其视为“创建经过身份验证的会话”。

加密

HTTPS 用于加密客户端和服务器之间的 HTTP 流量。在依赖认证用户和未认证用户的系统上,所有依赖用户认证的流量都需要通过 HTTPS 加密;没有办法解决这个问题。

这样做的原因是,如果您对用户进行身份验证,与他们共享一个秘密(他们的会话 ID 等),然后开始在纯 HTTP 中展示该秘密,他们的会话可能会被中间人劫持攻击。黑客将等待流量通过观察到的网络并窃取机密(因为它是通过 HTTP 的纯文本),然后假装是原始客户端发起与您的服务器的连接。

人们解决此问题的一种方法是将请求远程 IP 地址与经过身份验证的会话相关联。单独这样做是无效的,因为任何黑客都能够在他们的虚假请求中欺骗他们的请求远程 IP 地址,然后观察你的服务器发回的响应。大多数人会争辩说,除非您正在跟踪历史数据并使用它来识别特定用户的登录模式(就像 Google 所做的那样),否则这甚至不值得实施。

如果您需要在 HTTP 和 HTTPS 部分之间拆分您的站点,HTTP 流量必须不发送或接收会话 ID 或任何用于管理用户身份验证状态的令牌。请勿在非 HTTPs 请求/响应中发送敏感的应用程序数据,这一点也很重要。

在 Web 应用程序/API 中保护数据的唯一方法是加密您的流量。

您的主题一个接一个

基本-Http-Auth

身份验证:是 会话管理:否 加密:否

这是一种仅通过网络资源进行身份验证的方法。基本身份验证通过 URL 标识的资源对使用进行身份验证。这是 Apache HTTP Web Server 最常用的实现方式,它使用基于 .htaccess 的目录/位置身份验证。每个请求都必须发送凭据;客户通常会为用户透明地处理此问题。

基本身份验证可以被其他系统用作身份验证模式。但是,使用 Basic-Http-Auth 的系统提供的是身份验证和会话管理,而不是 Basic-Http-Auth 本身。

这不是会话管理。 这不是加密;内容和凭据几乎是 100% 纯文本 这不会保护应用程序的 HTTP 请求/响应的内容。

摘要式验证

身份验证:是 会话管理:否 加密:否

这与 Basic-Http-Auth 完全相同,只是添加了一些简单的 MD5 消化。不应依赖这种摘要而不是使用加密。

这不是会话管理。 这不是加密;摘要很容易被破坏 这不会保护应用程序的 HTTP 请求/响应的内容。

OAuth

身份验证:是 会话管理:否 加密:否

OAuth 只是让您有一个外部服务来验证凭据。之后,由您来管理/处理向您的 OAuth 提供者提出的身份验证请求的结果。

这不是会话管理。 这不是加密;您的网站流量仍然是纯文本。由于 HTTPS 限制,身份验证过程将是安全的,但您的应用仍然容易受到攻击。 这不会保护应用程序的 HTTP 请求/响应的内容。

Gangster Handshake / 自定义 HTTP 标头

身份验证:是,可能 会话管理:是的,可能 加密:否

“自定义 HTTP 标头”是“Gangster Handshakes”的一种;因此,我将使用相同的部分来讨论它们。唯一的区别是“自定义 HTTP 标头”指定了 hanshake(会话 ID、令牌、用户身份验证令牌等)的存储位置(即在 HTTP 标头中)。

需要注意的是,这些并没有指定如何处理身份验证,也没有指定如何处理会话管理。它们基本上描述了会话 ID/身份验证令牌的存储方式和位置。

身份验证需要由您的应用程序或通过第三方(例如 OAuth)处理。会话管理仍需要实施。有趣的是,您可以根据需要选择将两者合并。

这不是加密;您的网站流量仍然是纯文本。如果您使用 OAuth,由于 HTTPS 限制,身份验证过程将是安全的,但您的应用程序仍然容易受到攻击。 这不会保护应用程序的 HTTP 请求/响应的内容。

你需要做什么

...我强烈建议您确保您了解一个强大且安全的 Web 应用程序需要以下内容:

    加密(HTTPS 几乎是您唯一的选择) 会话管理 身份验证/授权

授权依赖于身份验证。身份验证依赖于会话管理和加密确保会话不被劫持并且凭据不被截获。

Flask-登录

我认为您应该研究 flask-login 作为避免重新实现***的一种方式。我个人从未使用过它(我在 python 中将金字塔用于 Web 应用程序)。但是,我之前在 web 应用程序/python 板上看到过它。它处理身份验证和会话管理。通过 HTTPS 抛出您的 Web api/应用程序,您将拥有全部三个(加密、会话管理和用户身份验证)。

如果您不/不能使用flask-login,请准备好自己编写,但首先要研究如何创建安全的身份验证机制。

如果可能,如果您不了解如何编写身份验证程序,请不要在未了解黑客如何使用基于模式的攻击、定时攻击等之前尝试。

请加密您的流量

...摆脱通过一些“聪明”的令牌使用可以避免使用 HTTPS 的想法。摆脱应该避免使用 HTTPS/加密的想法,因为它“速度慢”、进程密集等。它是进程密集型的,因为它是一种加密算法。确保用户数据和应用程序数据安全的需要始终是您的首要任务。您不想经历通知用户他们的数据已被泄露的恐惧。

【讨论】:

典型网络应用的绝佳答案。但我相信 OP 正在询问 REST API 服务器的身份验证选项。例如,如果您的 REST API 使用 HTTP Basic Auth/Digest Auth,则不需要会话管理。 @jemeshsu 他们是一回事。创建 REST API 与传统 Web 应用程序在会话管理、身份验证/授权和传输加密方面几乎没有区别。【参考方案2】:

https 比较慢,但不是。 只有握手更慢。对我们来说,最大的问题是维护服务器-移动端的密钥对和权利。 我们也实现了消息摘要。问题是:很难正确设置 php-android-ios 版本。完成此操作后(一个参数需要更改最初建议 Google 仅在 android 端产生的结果)问题将出在低端设备上:CPU 使用率高,解密加密过程慢,比 https 慢很多,特别是当您需要转换 10kb 字符串时(可能需要几分钟)。

如果我不将美国国家航空航天局的数据传输到哈马斯,那么我会通过简单的 HTTP 进行非常简单的加密:比如反转比特左右......

【讨论】:

【参考方案3】:

使用 HTTPS。它(略微)较慢,但是您在相对较短的投资时间内(购买 SSL 证书并将您的 URL 从 http 更改为 https)从中获得的安全性是值得的。如果没有 HTTPS,您将面临用户会话在不安全的公共网络上被劫持的风险,这非常easy for someone to do。

【讨论】:

以上是关于Web App (angular)、iOS 和 Android 可以使用的安全 RESTful API的主要内容,如果未能解决你的问题,请参考以下文章

使用 MSAL 保护 ASP.Net Core Web API 和 Angular App

Angular 4 App调用Play Framework Web App的CORS问题

Angular 2 app base href 与 Cordova IOS

Web Api 2 和 Angular 之间的 CORS 错误

iOS中web app调试(mac).md

刷新/重新加载Angular 2 Web App