我有一个即将开展的项目,网页将进行AJAX调用。外部客户端还将提供REST API。我将使用带有Web API的ASP.NET MVC 4来实现这个项目。
我在网上看到了各种人们使用[Authorize]
属性进行安全性的示例。我认为这是通过网页上的AJAX调用Web API的时候。
我还看到了各种示例,其中API密钥与每个请求一起传递(通过查询字符串或标头)。我认为这是从外部系统调用Web API的时候。
以下是立即浮现的问题:
一位同事指出,我可能希望将API部署到与托管Web应用程序的URL完全不同的URL。同样,他指出外部API可能需要更粗糙的颗粒或单独进化。
我不想在这里重新发明轮子。这让我想知道我是否应该首先使用Web API作为我的AJAX调用的内部API,或者我是否应该坚持使用[HttpPost]
属性的旧学校MVC操作。
答案 0 :(得分: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
作为身份验证的结果,您就可以使用不同的身份验证方法。如果您有两个处理程序(如果是Web主机,则为HttpModules
)或Web API 2中的身份验证过滤器,您可以根据不同的因素建立身份。例如,您可以将BasicAuthnHandler
和ApiKeyHandler
添加到config.Handlers
,从而依次在Web API管道中运行。他们可以做的是查找凭据并设置Thread.CurrentPrincipal
。如果基本方案中包含Authorize
标头,则BasicAuthnHandler
将进行身份验证并设置Thread.CurrentPrincipal
,如果API密钥进入,则不执行任何操作,ApiKeyHandler
设置Thread.CurrentPrincipal
。两个处理程序都可以创建相同类型的主要说法GenericPrinicpal
或甚至不同的。这并不重要,因为所有主体都必须实现IPrincipal
。因此,在Authorize
过滤器运行时,Thread.CurrentPrincipal
将被设置,无论您如何进行身份验证,授权都将起作用。注意:如果您是网络托管服务商,除了HttpContext.User
之外,您还需要设置Thread.CurrentPrincipal
。
答案 1 :(得分:2)