如何使 WebAPI 操作只能从我的应用程序访问? [英] How to make WebAPI actions accessible only from my app?

查看:12
本文介绍了如何使 WebAPI 操作只能从我的应用程序访问?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

A common use case for WebAPI would be to have shell views rendered by MVC controllers, which contain javascript that then hit your API to access data.

但是假设您有一些昂贵的 API 操作,并且您不希望人们远程访问这些端点——您只希望您的应用程序提供的 MVC 视图能够访问它们.你怎么能去保护他们?

But let's say you have some expensive API operations and you don't want people remotely accessing those endpoints -- you only want your MVC views, delivered by your application, to access them. How could you go about protecting them?

在这种情况下 Request.IsLocal 不起作用,因为 javascript 正在从他们机器上的客户端浏览器调用它.即使它确实有效,您也需要挖掘以获取真正的 HttpContext 才能找到此属性——而该解决方案在自托管 WebAPI 中不起作用.

In this case Request.IsLocal doesn't work, because javascript is invoking it from the client's browser on their machine. Even if it did work, you need to dig to get the real HttpContext in order to find this property -- and that solution wouldn't work in self-hosted WebAPI.

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

For API endpoints that require a valid IPrincipal, you could protect them with the [Authorize] attribute. But what about API endpoints that you want your app to be able to access for anonymous users?

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

I have tried a solution and will post it separately as an answer, because I'm not sure if it's the best (or even a good) approach.

推荐答案

在你喋喋不休地谈论你尝试过什么"之前,这里是我已经尝试过的.有用.只是不确定是否有更好的方法.

Before you go harping about "what have you tried", here is what I have tried. It works. Just not sure if there is a better way.

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

  1. Create an MVC action filter and add it as a global filter during Application_Start.

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

Create an Http (WebAPI) action filter and use it on actions that should reject remote requests.

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

The global MVC filter does this:

  1. 在请求中查找特定的 cookie.如果 cookie 存在,则解密其值.解密后的值应该是 DateTime 的字符串表示,因此使用 DateTime.TryParse 将其取出.如果该值被正确解析为 DateTime,并且 DateTime 不到一天,请在此处停止,什么也不做.

  1. Looks for a specific cookie in the request. If the cookie is there, its value is decrypted. The decrypted value should be a string representation of a DateTime, so use DateTime.TryParse to get it out. If the value is correctly parsed to a DateTime, and that DateTime is less than a day old, STOP HERE and do nothing else.

如果 cookie 不存在,或者无法解密/解析,或者超过一天,则向浏览器写入一个新的 cookie.使用当前的DateTime.UtcNow.ToString()作为值,加密,用HttpOnly = false写入.

If the cookie is not there, or cannot be decrypted / parsed, or is older than a day, write a new cookie to the browser. Use the current DateTime.UtcNow.ToString() as the value, encrypt it, and write it with HttpOnly = false.

WebAPI 过滤器执行此操作:

The WebAPI filter does this:

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

如果该值是有效的 DateTime 并且小于 2 天,请在此处停止并且不执行任何其他操作.

If the value is a valid DateTime and is less than 2 days old, STOP HERE and do nothing else.

否则,抛出 403 Forbidden 异常.

Otherwise, throw a 403 Forbidden exception.

关于我当前实现的一些说明.首先,我使用带有共享秘密和盐的 AES 加密.共享密钥作为 appSetting 存储在 web.config 中.对于盐,我启用了匿名识别并使用 Request.AnonymousID 作为盐.我并不完全喜欢盐,因为在 WebAPI 控制器中使用它更难,但只要它不是自托管的,就不是不可能的.

A couple of notes about my current implementation of this. First of all, I use AES encryption with a shared secret and a salt. The shared secret is stored as an appSetting in web.config. For the salt, I enabled anonymous identification and used Request.AnonymousID as the salt. I'm not entirely fond of the salt because it's tricker to get at in a WebAPI controller, but not impossible as long as it is not self-hosted.

这篇关于如何使 WebAPI 操作只能从我的应用程序访问?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆