2

情况

我有一个即将进行的项目,其中网页将进行 AJAX 调用。还将为外部客户端提供 REST API。我将使用带有 Web API 的 ASP.NET MVC 4 来实现这个项目。

我在网上看到了各种例子,人们使用该[Authorize]属性来保证安全。我认为这是每当通过网页上的 AJAX 调用 Web API 时。

我还看到了各种示例,其中 API 密钥与每个请求一起传递(通过查询字符串或标头)。我认为这是每当从外部系统调用 Web API 时。

问题

以下是立即浮现在脑海中的问题:

  • 我应该为内部和外部客户端创建一个单独的控制器吗?
  • 还是我应该强制网页使用相同的外部身份验证模型?
  • 或者有没有办法让外部客户端可以使用 Authorize 属性?
  • 或者我应该以某种方式同时支持两种形式或身份验证?

旁注

一位同事指出,我可能希望将 API 部署到与托管 Web 应用程序的位置完全不同的 URL。同样,他指出外部 API 可能需要更粗粒度或单独发展。

我不想在这里重新发明轮子。[HttpPost]这让我想知道我是否应该首先使用 Web API 作为我的 AJAX 调用的内部 API,还是应该坚持使用带有属性的老式 MVC 操作。

4

1 回答 1

4

[Authorize]属性不仅仅适用于 Ajax。当您将[Authorize]属性应用于操作方法时,它的作用是确保在操作方法运行之前对身份进行身份验证,无论客户端发出请求,也无论提交给您的 API 的凭据类型如何。它寻找的只是Thread.CurrentPrincipal. 这是Authorize过滤器中代码的复制粘贴。

protected virtual bool IsAuthorized(HttpActionContext actionContext)
{
    ...
    IPrincipal user = Thread.CurrentPrincipal;
    if (user == null || !user.Identity.IsAuthenticated)
    {
        return false;
    }
    ...
}

如您所见,它所做的一切都是获取Thread.CurrentPrincipal并检查身份是否经过身份验证。当然,当您包含角色时,还有其他检查。

因此,这意味着您将能够使用不同的身份验证方式,只要Thread.CurrentPrincipal设置为身份验证的结果。如果您有两个处理程序(或HttpModules在 Web 托管的情况下)或 Web API 2 的身份验证过滤器,您可以根据不同的因素建立身份。例如,您可以将 aBasicAuthnHandler和 aApiKeyHandler添加到config.HandlersWeb API 管道中,从而一个接一个地在 Web API 管道中运行。他们可以做的是寻找凭证并设置Thread.CurrentPrincipal. 如果Authorizeheader 出现在基本方案中,BasicAuthnHandler将进行身份验证和设置Thread.CurrentPrincipal,如果 API 密钥出现,它什么也不做并ApiKeyHandler设置Thread.CurrentPrincipal。两个处理程序都可以创建相同类型的主体说GenericPrinicpal甚至是不同的。没关系,因为所有主体都必须执行IPrincipal。因此,在Authorize过滤器运行时,Thread.CurrentPrincipal无论您如何进行身份验证,都将设置并且授权将起作用。注意:如果您是虚拟主机,HttpContext.User除了Thread.CurrentPrincipal.

于 2013-07-03T01:29:52.547 回答