存储在CallContext中的数据是否可以在请求之间泄漏?

时间:2014-04-08 08:46:17

标签: c# asp.net-mvc

在MVC应用程序中,我需要存储一些用户数据以验证他是否具有访问某些页面的所有权限(例如他是对象的所有者等)。我尝试在我的一个服务中添加一个私有静态字段来处理用户数据,并添加一个静态的get-only属性来访问私有字段。如果私有字段为null,则此属性从数据库中提取用户数据。显然这是一个坏主意,因为MVC应用程序不仅仅在请求期间存在,所以一旦设置了私有静态字段,它就会无限期地停留在那里。

搜索上述解决方案的替代方案,使我获得了ThreadStatic属性。这似乎工作得很好(至少在第一眼看上去)。但后来我阅读了更多有关该属性的内容,发现一个请求实际上可以由多个线程处理(在我的情况下,这不是特别的问题),并且一些线程可以在多个请求中重用(极端,但显然很少见的情况) )。现在这听起来像是一个真正的问题,这意味着我曾经从数据库中提取的用户数据可能泄漏到另一个请求,并且可以根据另一个用户的数据验证一个用户。

所以我搜索了另一个替代方案并找到了CallContext。这次我还注意到人们发出警告说它可能不会像人们期望的那样工作。如果ThreadStatic poeple解释使用它有什么风险,但CallContext的情况不是那么多。

因此,存储在CallContext中的数据是否会从一个请求泄漏到另一个请求(就像ThreadStatic字段可能发生的那样),或者可能发生的最坏情况是在请求中间丢失数据(我可以忍受)?

3 个答案:

答案 0 :(得分:2)

  

在MVC应用程序中,我需要存储一些用户数据以验证他是否拥有所有用户数据   访问某些页面的权利(比如他是对象的所有者)   等)。

您正在寻找的是HttpContext.Session@Ron's answer建议。您需要启用会话支持。

OTOH,HttpContext.Items的生命周期仅限于给定的HTTP请求,它不会在请求之间流动。一些HTTP协议文本状态数据(例如cookie)将通过HttpContext.Current.Request流动。

  

CallContext中存储的数据是否会在请求之间泄漏?

如果您仍想知道逻辑调用上下文数据(CallContext.LogicalGetData / CallContext.LogicalSetData)是否在不同的HTTP请求之间流动,答案将是。如果确实如此,那将是一个严重的安全漏洞,因为不同的请求可能来自不同的用户。

然而,它确实在同一请求中的线程之间流动,因此就此而言,它可以用作ThreadLocal的替代。尽管如此,谨慎使用,因为有写作复制行为,请查看Stephen Cleary的博客for more details。如果您使用异步控制器方法和async / await(或ContinueWith等),则可能只需要它。

答案 1 :(得分:1)

根据this post,您应该使用HttpContext而不是CallContext。

顺便说一句,HttpContext是“按请求”,如果你想保存数据库访问,可以使用“Session”,通过创建一个AbstractController,可以避免控制器和动作之间的重复。

答案 2 :(得分:1)

我当前的堆栈是WCF,而不是ASP.Net,但我想提供标题中给出的OP问题的答案:

与我在网络上遇到的所有资源相反,与accepted answer of @noseratio相反,也与理性(重大安全漏洞等)相反,我认为至少对于WCF,正确答案是正确的,是:

是的

我想小心一点,并指出我不完全理解其推理,因此我无法确定性地重现这一点。不过,由于我怀疑可能是由于我们在公司中遇到的一些零星异常而导致的,因此我建立了一个实验,在其中存储OperationContext.Current.IncomingMessageHeaders.Action(在WCF中,这是操作的名称),然后通过CallContext.LogicalSetData()重新刷新一百万次,并等待偶发异常的断点出现。当它最终完成时,我将存储的值与OperationContext.Current.IncomingMessageHeaders.Action进行了比较,并且动作(因此请求)不同。

可能是相关的:在我的WCF应用程序中读写LogicalCallContext的代码正在MessageInspector内部运行。

不幸的是,我缺乏深入的知识来创建稳定的工作再现示例。请询问我可能忽略的任何其他相关细节,例如配置值,环境变量等,以面对我的测试用例可能是错误的。我发现自己的发现有些令人震惊,甚至不太可能,我会乐于纠正。在此之前,我认为与社区共享是个好主意。

.Net Framework版本:4.7.2。

WCF服务托管在IIS中。


您可以找到有关我在Stephen Cleary's blog post上对LogicalCallContext的观察的一些其他信息(请参阅评论部分)。