4

哪些选项可用于对要由来自另一个域的 JQuery 应用程序使用的 MVC3 Web API 应用程序进行身份验证?

以下是我迄今为止尝试过的限制/事情:-

  • 我不想使用 OAuth;对于用户群有限的私人应用程序,我不能期望最终用户在现有提供商上拥有他们的帐户,并且没有实施我自己的空间
  • 我已经有一个功能齐全的 HMAC-SHA256 实现,使用标头中传递的数据工作得很好;但这在 IE 中不起作用,因为 IE8/9 中的 CORS 已损坏并且不允许您发送标头
  • 我需要跨域,因为消费应用程序与 API 位于不同的域中,但不能使用 jsonp,因为它不允许您使用标头
  • 我想避免基于令牌(仅)的方法,因为这是可以重放的,并且由于有状态而违反了 REST

在这一点上,我接受了 HMAC-SHA256 方法,该方法使用 URL 或查询字符串/post 来提供散列和其他变量。

将这些变量放在 URL 中似乎很脏,将它们放在查询字符串/帖子中是一种痛苦。

我成功地使用了 JQuery $.ajaxSetup beforeSend 选项来生成哈希并将其附加到标头,但正如我所提到的,您不能在 IE8/9 中使用标头。

现在我不得不求助于 $.ajaxPrefilter,因为我无法更改 beforeSend 中的 ajax 数据,也不能仅扩展 $.ajaxSetup 中的数据,因为我需要根据 ajax 的类型动态计算哈希值询问。$.ajaxPrefilter 也是一个问题,因为没有干净/简单的方法可以以与方法无关的方式添加所需的变量......即它必须是 GET 的查询字符串和 POST 的表单数据

我一定遗漏了一些东西,因为我找不到一个解决方案:-a)支持跨域 a)在 MVC 和 JQuery 方面都不是大规模的黑客攻击 c)实际上是安全的 d)适用于 IE8/9

必须有人在那里正确地做这件事......

编辑

澄清一下,API 端的身份验证机制很好......无论我以哪种方式验证请求,我都会生成一个 GenericPrincipal 并在 API 中使用它(这个优点是另一篇文章,但它确实允许我使用MVC 中的标准授权机制,我更喜欢自己滚动......较少让我的 API 上的其他开发人员学习和维护)

问题主要在于将身份验证信息从客户端传输到 API:- - 它不能依赖服务器/API 状态。所以我不能在一次调用中传递用户名/密码,取回一个令牌,然后继续使用该令牌(对重放攻击开放) - 任何需要使用请求标头的东西都不存在,因为 IE 使用 XDR 而不是 XHR 像其他的浏览器,并且它不支持自定义标头(我知道 IE10 支持 XHR,但实际上我需要 IE8+ 支持) - 我想我无法生成 HMAC 并将其传递到 URL 中的某处(路径或查询字符串)但是这个似乎是一个 hack,因为我使用的部分请求不是为此而设计的——如果我使用路径,会有很多混乱的解析,因为至少我必须为每个请求传递一个用户名、时间戳和哈希;

尽管很糟糕,querystring/formdata 似乎是最好的选择;但是现在我必须弄清楚如何在每个请求上捕获这些。我可以使用 MessageHandler 或 Filter,但都没有提供方便的方式来访问表单数据。

我知道我可以自己编写所有解析和处理的东西(看起来我会的)但关键是我无法相信已经没有解决方案。就像我有(1)对 IE 的支持,(2)安全和(3)干净的代码,我只能选择两个。

4

2 回答 2

3

你的要求对我来说似乎有点不合理。你不可能同时拥有一切,你必须愿意放弃一些东西。几点说明:

  • OAuth 似乎是您想要的,至少有一些修改。您可以使用 Azure 的访问控制服务,这样您就不必实现自己的令牌提供程序。这样,您就“外包”了安全令牌提供程序的实施。最后我检查了 Azure ACS 是否仍然免费。当您查找 ACS 文档时会出现很多混乱,因为人们大多使用它来插入 Facebook 或 Google 等其他提供商,但您可以将其调整为仅作为您自己服务的令牌提供商。
  • 你似乎很担心重放攻击。重放攻击几乎总是有可能的。我必须只听通过线路的数据并将其发送到您的服务器,即使是通过 SSL。无论如何,重放攻击都是您需要处理的事情。通常我所做的是跟踪即将到来的请求的缓存并将哈希签名添加到我的缓存中。如果我在 5 分钟内看到另一个具有相同哈希的请求,我会忽略它。为此,我添加了请求的时间戳(毫秒粒度)和 URL 的一些派生值作为我的哈希参数。这允许每毫秒从同一客户端对同一地址进行一次操作,而不会将请求标记为重放攻击。
  • 你提到了 jQuery,如果你使用散列方法,这让我有点困惑。这意味着您实际上在客户端上有哈希算法和签名逻辑。这是一个严重的缺陷,因为只需检查 javascript,我现在就可以确切地知道如何签署请求并将其发送到您的服务器。
于 2013-02-23T21:15:55.297 回答
1

简单地说;在身份验证方面,ASP.NET WebAPI 并没有什么特别之处。

我可以说的是,如果您将它托管在 ASP.NET 中,您将获得 ASP.NET 对身份验证和授权的支持。如果您选择了自托管,则可以选择启用 WCF 绑定安全选项。

在 ASP.NET 中托管 WebAPI 时,您将有几个身份验证选项:

  1. 基本认证
  2. 表单身份验证 - 例如,从任何 ASP.Net 项目中,您可以启用 Authentication_JSON_AppService.axd 以进行表单身份验证
  3. Windows 身份验证 - HttpClient/WebHttpRequest/WebClient
  4. 或者明确允许匿名访问您的 WebAPI 的方法
于 2013-02-23T18:06:18.020 回答