在Asp.Net中模拟用户

时间:2020-03-06 14:41:49  来源:igfitidea点击:

我的DBA要求所有数据库访问都必须通过受信任的域帐户来完成。如果设置了web.config,则可以完成此操作。这要求用户登录或者位于IE的域中,以通过凭据。我想通过使用代码来模拟用户。我正在使用此知识库文章中找到的代码:

http://support.microsoft.com/kb/306158

效果很好,我传入了凭据,模拟了用户,然后调用了数据库并返回了数据。

问题是,如果我转到另一个页面,则会丢失我的模拟凭据。这意味着每当我调用数据库时,都必须运行模拟代码。

如果IIS可以模拟所有页面的域用户,那么为什么在使用代码时不能模拟用户?

似乎与线程上下文切换有关。我尝试在Aspnet.config文件中设置alwaysFlowImpersonatingPolicy,但它不起作用。

http://msdn.microsoft.com/zh-CN/library/ms229553.aspx

有什么建议吗?甚至有可能做我想做的事吗?

解决方案

丢失模拟上下文的原因是,每次新页面请求结束时,模拟上下文都会超出范围。

按照docs <alwaysFlowImpersonationPolicy>的使用,以确保在异步调用之间保持相同的模拟上下文。例如,当对远程Web服务进行异步调用时,回调模拟上下文与发起线程相同。对于ASP.NET,模拟上下文仅在页面请求的生存期内流过。

模拟发生在线程级别。模拟使通常从进程继承的线程的访问令牌被替换。最佳做法是在完成需要模拟的操作后,尽快还原模拟的效果,并因此还原标记。对于IIS或者ASP.NET来说,故事没有什么不同。每个请求通常由不同的线程处理,因此我们必须使每个线程都冒充用户。

This means every time I make a call to
  the database I have to run the
  impersonate code.

这是正确的。

If IIS can impersonate a domain user
  for all pages, then why can I not
  impersonate a user while using code?

IIS并没有做任何不同的事情,因此它可能只是一种幻觉。它不能模拟所有页面的用户,除非所有页面都由同一线程提供服务,并且在提供每个页面时从不还原模拟令牌。

It seems to be something with thread
  context switching.

并不真地。除非我们正在执行异步处理(我们不会在问题中声明自己要这样做),否则模拟上下文的流程将是无关紧要的。如果在处理单个请求期间直接或者间接导致线程切换,则只需要担心模拟上下文的流动。如果希望辅助线程(工作线程)在主要线程的模拟上下文下继续进行工作,则需要确保辅助线程借用模拟令牌。在.NET Framework 1.1中,我们必须格外小心并手动编排模拟上下文的流程。但是,在.NET 2.0中,引入了ExecutionContext API,并且进行了大量繁重的工作。