首页 文章

针对Web应用和移动应用的REST API身份验证

提问于
浏览
42

我在决定如何为RESTful API实现身份验证时遇到一些麻烦,这些API对于Web应用程序和移动应用程序都是安全的 .

首先,我考虑通过HTTPS调查HTTP基本身份验证作为选项 . 它适用于移动应用程序,其中用户名和密码可以安全地存储在操作系统密钥链中,并且由于请求将通过HTTPS而无法在传输过程中被截获 . API也很优雅,因为它完全是无状态的 . 这个问题是针对Web应用程序的 . 将无法访问用于存储用户名和密码的密钥链,因此我需要使用cookie或localStorage,但随后我将用户的私人详细信息存储在易于访问的位置 .

经过更多的研究,我发现了很多关于HMAC认证的讨论 . 我用这种方法看到的问题是需要一个只有客户端和服务器知道的共享秘密 . 如何在Web应用程序中为特定用户获取每个用户的秘密,除非我有一个api / login endpoints ,它接受用户名/密码并将秘密返回存储在cookie中?在将来的请求中使用 . 然而,这是向API引入状态 .

为了让另一个扳手投入工作,我希望能够将API限制为某些应用程序(或者,能够阻止某些应用程序使用API) . 我无法看到这个网络应用完全公开的可行性 .

我真的不想实现OAuth . 这可能对我的需求有些过分 .

我觉得好像我可能没有完全理解HMAC,所以我欢迎一个解释,以及如何通过网络应用程序和移动应用程序安全地实现它 .

更新

我最终使用HTTP Basic Auth,但是不是每次请求都提供实际的用户名和密码,而是实现 endpoints 以交换访问密钥的用户名和密码,然后为每个经过身份验证的请求提供访问密钥 . 消除了在浏览器中存储用户名和密码的问题,但当然如果您有权访问该计算机并使用它,您仍然可以删除令牌 . 事后看来,我可能会进一步研究OAuth,但对初学者来说这很复杂 .

3 回答

  • 19

    你应该使用OAuth2 . 方法如下:

    1) Mobile App

    您自己陈述的移动应用程序存储客户端凭据 . 然后使用"Resource Owner Password Credentials Grant"(请参阅http://tools.ietf.org/html/rfc6749#section-4.3)发送这些凭据 . 反过来,它获得了可以在以下请求中使用的(承载)令牌 .

    2) Web site

    该网站使用"Authorization Code Grant"(见http://tools.ietf.org/html/rfc6749#section-4.1):

    • 网站看到未经授权的请求,并将浏览器重定向到REST API中支持HTML的自动化 endpoints .

    • 用户使用REST服务进行身份验证

    • REST站点使用URL中的访问令牌将用户重定向回网站 .

    • 网站调用REST站点并将访问令牌交换为授权令牌 .

    此后,网站使用授权令牌访问REST服务(代表最终用户) - 通常通过在HTTP授权标头中将令牌作为“承载”令牌包含在内 .

    这不是火箭科学,但确实需要一些时间来完全理解 .

    3) Restricting API access for certain applications

    在OAuth2中,每个客户端都会获得一个客户端ID和客户端密钥(此处“客户端”是您的移动应用程序或网站) . 客户端必须在授权时发送这些凭据 . 您的REST服务可以使用它来验证调用客户端

  • 2

    解决API用户身份验证问题的一种方法是在用户登录时从API请求身份验证令牌 . 然后,此令牌可用于后续请求 . 你已经触及过这种方法 - 听起来很棒 .

    关于限制某些Web应用程序 . 您需要让每个Web应用程序通过每个请求标识自己,并在API实现中执行此身份验证 . 挺直的 .

  • 2

    我非常轻松,安全地解决了这个问题,而无需公开任何客户端凭据 .

    我还将问题分成两部分 . API身份验证 - 这是来自已识别实体(网站或本机应用程序)的有效请求 . API授权,是允许使用此特定 endpoints 和HTTP谓词的实体 .

    使用访问控制列表以及根据需要在API代码,配置和数据库中设置的用户权限和设置,将授权编码到API中 . API中的简单if语句可以测试授权并返回相应的响应(未授权或处理API调用的结果) .

    验证现在只是检查呼叫是否是真实的 . 为此,我向客户发出自签名证书 . 只要他们想要,就可以从他们的服务器调用API - 通常是在他们生成第一页时(或者当他们执行自己的应用程序登录检查时) . 此调用使用我之前提供的证书 . 如果在我身边,我很高兴证书有效我可以返回一个nonce和一个限时生成的API密钥 . 此密钥用于所有后续调用其他API endpoints ,例如,在承载标头中,它可以非常公开地存储在HTML表单字段或javascript变量或应用程序内的变量中 .

    nonce将阻止重放攻击,如果有人想要,API密钥可能会被窃取 - 它们在过期后无法继续使用,或者nonce在下次调用之前发生变化 .

    如果nonce不匹配,每个API响应都将包含下一个nonce,它将返回一个身份验证错误 . 实际上nonce不匹配我也杀了API密钥 . 然后,这将强制真正的API用户使用证书重新进行身份验证 .

    只要最终用户保持这些证书的安全,并且不公开他们用来进行初始身份验证调用的方法(比如使它成为可以重放的ajax请求),那么API就很好而且安全 .

相关问题