如何只从我的应用程序访问Web API操作?

时间:2013-03-12 16:15:23

标签: asp.net-mvc asp.net-mvc-4 asp.net-web-api security

WebAPI的一个常见用例是使用MVC控制器呈现shell视图,其中包含javascript然后命中您的API以访问数据。

但是,让我们说您有一些昂贵的API操作,并且您不希望人们远程访问这些端点 - 您只希望您的应用程序提供的MVC视图访问它们。你怎么能保护它们?

在这种情况下,Request.IsLocal无法正常工作,因为javascript正在其计算机上的客户端浏览器中调用它。即使它确实有效,你需要挖掘才能获得真正的HttpContext才能找到这个属性 - 而且这个解决方案在自托管的WebAPI中不起作用。

对于需要有效IPrincipal的API端点,您可以使用[Authorize]属性保护它们。但是,您希望应用能够为匿名用户访问的API端点呢?

我尝试了一个解决方案,并将其单独发布作为答案,因为我不确定它是否是最佳(甚至是好的)方法。

2 个答案:

答案 0 :(得分:2)

如果您的MVC站点使用身份验证,则可以为Web API方法启用表单身份验证。您可以编写一个自定义[Authorize]属性,该属性将检查是否存在将从AJAX调用发送的表单身份验证cookie,如果存在则构造主体。

另一种可能的解决方案是使用tokens保护您的API,这是一种更加RESTful的风格。这里的想法是,当用户在您的MVC网站上进行身份验证时,您可以生成令牌并将其传递给视图,该令牌将在向Web API发送AJAX请求时使用,后者将验证令牌及其签名的有效性。

另一方面,如果您的网站不使用身份验证,那么事情会变得非常复杂,因为您无法知道请求是否来自受信任的客户端,因为您使用的是javascript来调用API方法。

答案 1 :(得分:2)

在你开始讨论“你尝试过什么”之前,我已经尝试过了。有用。只是不确定是否有更好的方法。

  1. 创建MVC操作过滤器,并在Application_Start期间将其添加为全局过滤器。

  2. 创建一个Http(WebAPI)操作过滤器,并将其用于应拒绝远程请求的操作。

  3. 全局MVC过滤器执行此操作:

    1. 在请求中查找特定的Cookie。如果cookie在那里,则其值被解密。解密后的值应该是DateTime的字符串表示形式,因此请使用DateTime.TryParse将其删除。如果该值已正确解析为DateTime,并且DateTime不到一天,则停止此处,不执行任何其他操作。

    2. 如果cookie不存在,或者无法解密/解析,或者超过一天,请向浏览器写一个新的cookie。使用当前DateTime.UtcNow.ToString()作为值,对其进行加密,然后使用HttpOnly = false进行编写。

    3. WebAPI过滤器执行此操作:

      1. 在请求中查找特定的Cookie。如果cookie在那里,请解密其值并尝试将其解析为DateTime

      2. 如果该值为有效DateTime并且不到2天,请停止此处,不做任何其他操作。

      3. 否则,抛出403 Forbidden异常。

      4. 关于我目前执行此操作的几点说明。首先,我使用AES加密共享秘密和盐。共享密钥在web.config中存储为appSetting。对于salt,我启用了匿名标识并使用Request.AnonymousID作为salt。我并不完全喜欢盐,因为在WebAPI控制器中使用它是一种琐事,但只要它不是自托管的,就不是不可能的。