用Javascript保护OAuth

| 我有一个使用OAuth 1.0a对其进行身份验证的应用程序的API。它取代了一个旧的api,该api使用了许多已弃用的自定义构建和大杂烩调用。 众所周知,OAuth 1.0a在(客户端)Javascript中并不安全,因为它依赖于将用户机密保密。由于源始终可见,因此这是不可能的。 我们拥有适用于Chrome,Firefox,IE和Safari的浏览器扩展,以后需要使用此api。这些扩展全部或大部分用Java语言编写,因此存在安全性问题。 这些扩展是内部的,因此可以使用自定义身份验证方法来获取其访问令牌。 我打算实施以下内容: 用户在浏览器中登录网站。 该网站向他们发出带有会话密钥的cookie。 然后,我们的扩展程序获取该cookie,并将其传递给api。 该api验证它是有效的活动会话,并向扩展发布其访问令牌。 这些令牌在过期之前最多可持续一小时。 javascript发出的Cookie的速率也将降低。 它在以下假设下运行: 如果另一个应用程序可以访问您的cookie,则它们仍然可以在网站上模拟您,因此访问api也不例外。 所有身份验证方法仍将通过我们的控制。 令牌的定期到期意味着,如果令牌遭到破坏,则剥削的时间将很有限。 我的问题是,这是限制对api的访问的安全方法吗? 还有更好的吗? 几个注意事项。 我知道,chrome扩展程序可以请求访问给定站点的Cookie的许可。我相信Firefox扩展也可以这样做。 显然,我们不希望通过任何页面上的javascript访问cookie,否则我们将遭受XSS攻击,因此仅需要通过扩展名即可访问它们。     
已邀请:
我写了一个网站,该网站通过OAuth的JavaScript库进行OAuth登录。这是工作流程: 只有具有LocalStorage的浏览器才支持OAuth 登录表单将检查LocalStorage的OAuth密钥,如果存在OAuth密钥,则自动尝试OAuth登录。 登录表单上有一个用于“记住我”的复选框,因此用户可以在登录时为其创建OAuth令牌。 记住我的成功登录将: 查找或创建名称等于用户代理的ClientApplication,并在必要时创建令牌 在HTML响应中使用javascript标签进行响应。 javascript标记将调用带有标记作为参数传递的javascript函数。此功能会将OAuth令牌保存到LocalStorage。 OAuth登录尝试失败将: 在HTML响应中使用javascript标签进行响应。 javascript标记将调用javascript函数以清除OAuth令牌的LocalStorage设置。这将防止其他OAuth登录尝试 此过程还有更多细节,如果您需要我可以告诉您更多信息。     
事后想到这篇文章的人只有几点想法: \“这是否安全\”->取决于我们要防范的威胁。在以下几点中,我将假定该解决方案已经隐含了一个受信任的网络链接(以防止进行传输中的令牌或凭据拦截尝试)。但是,说明中缺少一个关键要素,因为它没有提及我们是保护API免受未经授权的用户(人类)还是未经授权的API客户端(例如在浏览器中运行的恶意扩展)的保护。前者可以通过可用的开放标准轻松实现,而人们应该忘记尝试阻止未经授权的扩展进行访问,因为该模型从根本上依赖于开源客户端技术。这与设计安全的身份验证/授权机制相比,还关系到工作站的安全性。我们仍然可以实现某种扩展身份验证机制,但是对于知道如何阅读扩展源代码的人来说,它将是无用的。 我们基本上可以通过两种方式设计平台。通过检测API允许查询身份验证服务。或使用基于令牌的访问,在这种访问中,API将在收到的每个请求中都请求有效令牌的存在,而无需成为其发射者。这意味着将身份验证服务扩展为一个新角色:API票证发行者,这很少引起兴趣。在阅读建议时,似乎我们通过将会话令牌转发到API来合并两个世界。错了首先,这不是设计基于cookie的会话令牌的原因。其次,它迫使API与用户身份验证服务的会话管理系统实现某种实时同步链接->我们可以轻松避免的耦合。 我将假定主要目的是保护API免受未经授权的用户的侵害,并且我们不会尝试依靠本地系统访问来解决威胁。 现在,考虑到我们将不会在API中实现身份验证逻辑,我们必须依靠用户对身份验证服务进行身份验证的模型,从而使任何基础扩展都可以请求访问令牌。 这将修改原始方案,如下所示: 用户使用浏览器登录网站。 网站发布包含会话密钥的cookie。 该扩展现在可以将票证请求发送到身份验证服务。请求将包含会话令牌(默认浏览器行为),因此将通过身份验证。 一旦扩展收到票证,扩展便将其转发到API并请求会话令牌。 API通过询问会话管理器来验证票证。如果会话管理器说“是,我已制作此票证并且它仍然有效”,则API会生成一个会话令牌并将其返回给扩展名。该令牌将插入所有后续请求中,而不是故障单中。这样可以避免会话管理器上不必要的工作量。 令牌(不要将其与票证混淆)可以具有很短的生命周期,例如几分钟->如果令牌过期,则扩展名将仅返回到身份验证服务并请求新的票证(返回上述步骤3)。 上面的解决方案基本上取决于票证和令牌的安全性。他们的设计必须至少对以下5种威胁实施对策:i)尝试猜测票证/令牌(足够安全的随机生成),ii)尝试计算票证/令牌(足够大的熵),iii)尝试重用票证/令牌(到期),iv)尝试篡改有效的票证/令牌(完整性检查),v)尝试在没有有效令牌/票证的情况下访问API(在API收到的每个请求中验证令牌) )。 这种方法的另一个优点是,我们可以通过发出扩展特定的令牌来优化资源分配,这又会触发API上的特定逻辑(减少API访问,缩短生存期,限制请求等)。 希望能帮助到你。     
因此,您在example.com上拥有一个网站,并且需要访问api.com。您的扩展程序假设用户已登录example.com,提取了会话cookie并将其传递给api.com以获取Oauth令牌。听起来很合理,但是有一些更简便的方法而不必编写浏览器插件。 在您的情况下,api.com将与example.com通信以验证会话cookie。这两个系统之间有很强的依赖性。 OAuth通常用于example.com和api.com不互相信任的地方。 由于两个系统之间已经相互信任,因此您可以做各种事情来简化体系结构: 您可以创建一个托管在example.com/api/*上的代理,以验证会话,然后盲目转发到api.com/*。就浏览器而言,没有跨域请求,因此一切正常。 您可以跨域使用联合登录。这比代理方法更为复杂,但是您可以轻松地找到平台的现有实现。     

要回复问题请先登录注册