Authentication 同一ASP.NET Web API的不同身份验证方案 形势

Authentication 同一ASP.NET Web API的不同身份验证方案 形势,authentication,asp.net-web-api,authorization,Authentication,Asp.net Web Api,Authorization,我有一个即将到来的项目,网页将进行AJAX调用。外部客户端还将提供一个RESTAPI。我将用ASP.NETMVC4和WebAPI实现这个项目 我在网上看到过很多例子,其中人们使用[Authorize]属性进行安全保护。我假设这是在网页上通过AJAX调用Web API时发生的 我还看到了各种示例,其中每个请求(通过查询字符串或标头)都传递了一个API密钥。我假定这是在从外部系统调用Web API时发生的 问题 以下是我马上想到的问题: 我是否应该为内部和外部客户端创建单独的控制器 或者我应该强制

我有一个即将到来的项目,网页将进行AJAX调用。外部客户端还将提供一个RESTAPI。我将用ASP.NETMVC4和WebAPI实现这个项目

我在网上看到过很多例子,其中人们使用
[Authorize]
属性进行安全保护。我假设这是在网页上通过AJAX调用Web API时发生的

我还看到了各种示例,其中每个请求(通过查询字符串或标头)都传递了一个API密钥。我假定这是在从外部系统调用Web API时发生的

问题 以下是我马上想到的问题:

  • 我是否应该为内部和外部客户端创建单独的控制器
  • 或者我应该强制网页使用相同的外部身份验证模型吗
  • 或者是否有一种外部客户端可以使用Authorize属性的方法
  • 或者我应该以某种方式同时支持两种形式或身份验证吗
旁注 一位同事指出,我可能希望将API部署到一个与web应用托管地完全不同的URL。按照同样的思路,他指出外部API可能需要更粗的粒度或单独演化


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

[Authorize]
属性不仅仅适用于AJAX。当您应用
[Authorize]
属性来表示操作方法时,它的作用是确保在操作方法运行之前对身份进行身份验证,而与发出请求的客户端以及提交给API的凭据类型无关。它所寻找的是
Thread.CurrentPrincipal
。下面是
授权
过滤器中代码的复制粘贴

protected virtual bool IsAuthorized(HttpActionContext actionContext)
{
    ...
    IPrincipal user = Thread.CurrentPrincipal;
    if (user == null || !user.Identity.IsAuthenticated)
    {
        return false;
    }
    ...
}
如您所见,它所做的一切都是获取
线程.CurrentPrincipal
,并检查身份是否经过身份验证。当然,当您包括角色时,还有其他检查


因此,这意味着您将能够使用不同的身份验证方法,只要身份验证的结果是
Thread.CurrentPrincipal
。如果在web API 2中有两个处理程序(如果是web主机,则为
HttpModules
)或身份验证过滤器,则可以基于不同的因素建立标识。例如,您可以将
BasicAuthnHandler
ApiKeyHandler
添加到
config.Handlers
中,从而在web API管道中逐个运行。他们可以做的是查找凭据并设置
Thread.CurrentPrincipal
。如果
Authorize
头出现在基本方案中,
BasicAuthnHandler
将进行身份验证并设置
Thread.CurrentPrincipal
,如果API密钥出现,它将不执行任何操作并且
ApiKeyHandler
设置
Thread.CurrentPrincipal
。两个处理程序都可以创建相同类型的prinicipal,比如说
GenericPrinicpal
,甚至可以创建不同的prinicipal。这并不重要,因为所有主体都必须实现
IPrincipal
。因此,当
Authorize
过滤器运行时,
Thread.CurrentPrincipal
将被设置,并且无论您如何进行身份验证,授权都将工作。注意:如果您是web主机,您还需要设置
HttpContext.User
,以及
Thread.CurrentPrincipal

[Authorize]
属性不仅仅适用于Ajax。当您应用
[Authorize]
属性来表示操作方法时,它的作用是确保在操作方法运行之前对身份进行身份验证,而与发出请求的客户端以及提交给API的凭据类型无关。它所寻找的是
Thread.CurrentPrincipal
。下面是
授权
过滤器中代码的复制粘贴

protected virtual bool IsAuthorized(HttpActionContext actionContext)
{
    ...
    IPrincipal user = Thread.CurrentPrincipal;
    if (user == null || !user.Identity.IsAuthenticated)
    {
        return false;
    }
    ...
}
如您所见,它所做的一切都是获取
线程.CurrentPrincipal
,并检查身份是否经过身份验证。当然,当您包括角色时,还有其他检查

因此,这意味着您将能够使用不同的身份验证方法,只要身份验证的结果是
Thread.CurrentPrincipal
。如果在web API 2中有两个处理程序(如果是web主机,则为
HttpModules
)或身份验证过滤器,则可以基于不同的因素建立标识。例如,您可以将
BasicAuthnHandler
ApiKeyHandler
添加到
config.Handlers
中,从而在web API管道中逐个运行。他们可以做的是查找凭据并设置
Thread.CurrentPrincipal
。如果
Authorize
头出现在基本方案中,
BasicAuthnHandler
将进行身份验证并设置
Thread.CurrentPrincipal
,如果API密钥出现,它将不执行任何操作并且
ApiKeyHandler
设置
Thread.CurrentPrincipal
。两个处理程序都可以创建相同类型的prinicipal,比如说
GenericPrinicpal
,甚至可以创建不同的prinicipal。这并不重要,因为所有主体都必须实现
IPrincipal
。因此,当
Authorize
过滤器运行时,
Thread.CurrentPrincipal
将被设置,并且无论您如何进行身份验证,授权都将工作。注意:如果您是web主机,除了
Thread.CurrentPrincipal
之外,还需要设置
HttpContext.User