安全的RESTful API,可供Web App(角度),iOS和Android使用

时间:2013-05-06 14:05:22

标签: android iphone oauth flask restful-authentication

我要制定出一个计划来开发一个RESTful API(Python的/瓶),可以通过我们的未来的Web应用程序(Angularjs)和移动应用(iOS版/ Android设备)。使用

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

  1. 使用Basic-Http-Auth并通过线路发送用于API的每个请求的普通(但https)用户名/密码。
  2. 使用Digest-Auth,这是密码的哈希,跟踪将是自动的。这适用于Web应用程序,但是我无法确认iPhone和Android是否会原生支持。如果他们这样做,这可能是一个简单的解决方案!
  3. 使用自定义http标头,我会在成功验证后在http标头中发送自定义Auth字符串。但是我必须确保我为用户发出的每个请求发送此身份验证代码。这使得它与1)完全相同,不同之处在于未使用普通密码,并且授权代码可以在没有任何风险的情况下过期。同样有问题的是跟踪授权代码,该代码不再像2)
  4. 那样自动化
  5. 使用OAuth是一种选择。但它很难建立起来。如果没有更好的方法,也许这是唯一的方法吗?
  6. 按照此great article中的说明保护像Amazon S3一样的API。简而言之,他说服务器和客户端都知道私钥,他们会用它来散列通信。这就像强盗握手,如果他知道帮派握手,你只会信任送货员。有人问:
  7.   

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

         

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

    因此换句话说,首先使用Web应用程序的方法甚至没有意义。老实说,我不明白这应该如何在移动设备上运行。用户下载我们的应用程序,如何将私钥从iphone发送到服务器?我转移它的那一刻,它将受到损害。

    我正在研究的越多,我越是优柔寡断。

    我希望能问一些以前做过这个并且可以分享经验的专业人士。非常感谢

3 个答案:

答案 0 :(得分:67)

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

简介

会话管理

默认情况下,HTTP事务是无状态的。 HTTP没有指定任何方法让您的应用程序知道已从特定用户发送HTTP请求(已验证或未验证)。

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

重要的是要记住会话ID'可以称为许多其他的东西。其中一些例子是:会话令牌,令牌等。为了保持一致性,我将使用会话ID'对于其余的回应。

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

  1. 它可以存储在cookie中 - 每个请求都会自动发送当前域的cookie。
  2. 可以在URL上发送 - 每个请求都可以在URL上发送会话ID,因为会话ID将保留在客户端历史记录中,因此不建议
  3. 它可以作为HTTP标头发送 - 每个请求都需要指定标题
  4. 大多数Web应用程序框架都使用Cookie。但是,依赖于JavaScript和单页设计的应用程序可能会选择使用HTTP标头/将其存储在服务器可观察到的其他位置。

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

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

    <强>验证

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

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

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

    1. 他们存储在服务器端的会话数据可以存储他们的用户ID /一些其他标志,表示该用户被认证为特定用户
    2. 另一个用户令牌可以像会话ID一样发送到客户端(通过未加密的HTTP与发送未加密的会话ID一样不安全)
    3. 两种选择都没问题。它通常归结为您正在使用的技术以及它们默认提供的功能。

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

      <强>加密

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

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

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

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

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

      您的话题一个接一个

      <强>基本-HTTP-AUTH

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

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

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

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

      <强>文摘-AUTH

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

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

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

      <强>的OAuth

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

      OAuth只是让您拥有外部服务验证凭据。之后,由您来管理/使用您的OAuth提供商的身份验证请求结果。

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

      黑帮握手 / 自定义HTTP标头

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

      &#34;自定义HTTP标头&#34;是一种&#34;大佬握手&#34 ;;因此,我将使用相同的部分来讨论它们。唯一的区别是&#34;自定义HTTP标头&#34;指定将存储hanshake(会话ID,令牌,用户身份验证toke等)的位置(即在HTTP头中)。

      请务必注意,这些内容并未指定如何处理身份验证,也未指定如何处理会话管理。它们实质上描述了会话ID /身份验证令牌的存储方式和位置。

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

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

      您需要做什么

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

      1. 加密(HTTPS几乎是您唯一的选择)
      2. 会话管理
      3. 身份验证/授权
      4. 授权依赖于身份验证。身份验证依赖于会话管理和加密,确保会话未被劫持,并且不会截获凭据。

        <强>烧瓶登录

        我认为你应该考虑flask-login作为避免重新实现轮子的方法。我个人从未使用它(我在python中使用pyramid用于web应用程序)。但是,我之前在Web应用程序/ python板中看到过它。它处理身份验证和会话管理。通过HTTPS扔你的web api /应用程序,你就拥有了这三个(加密,会话管理和用户身份验证)。

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

        如果可能的话,如果您不了解如何编写身份验证过程,请不要在没有首先了解黑客如何使用基于模式的攻击,计时攻击等的情况下尝试这样做。

        请加密您的流量

        ...超越了一个想法,即你可以避免使用HTTPS和一些聪明的&#34;令牌使用。超越了你应该避免使用HTTPS /加密的想法,因为&#34;它的速度很慢,过程密集等等。这是一个过程密集型,因为它是一种加密算法。确保用户数据和应用程序数据安全的必要性始终是您的首要任务。您不希望通知用户他们的数据已被泄露。

答案 1 :(得分:1)

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

如果我不将Nasa数据传输到哈马斯,那么我将使用简单的HTTP进行非常简单的加密:比如反转这些比特......

答案 2 :(得分:1)

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