ASP.. NET在连接到数据库时丢失用户上下文

本文关键字:用户 上下文 数据库 NET 连接 ASP | 更新日期: 2023-09-27 18:18:37

我们有一个应用程序,它使用基本身份验证和asp.net提示用户输入他们的AD凭据。净模拟。

应用程序然后使用以下连接字符串

连接到SQL Server
SqlClient.SqlConnection cnn = new SqlClient.SqlConnection();
cnn.ConnectionString = 
  "Server=" + MenuServer + ";" + 
  "Database= " + MenuDatabase + ";" + 
  "Trusted_Connection=Yes;" + 
  "Pooling = False;";
cnn.Open();

99%的情况下,这会很好地传递用户上下文,但偶尔我们会从SQL Server得到以下错误:

用户'WebServerName$'登录失败。原因:找不到与提供的名称匹配的登录

意味着它无法传递用户凭据,而是默认为IIS工作进程。有趣的是,当我们捕获错误时,当前用户仍然会被准确地记录为以下代码:

string userName = Environment.UserName;

:

  • 集成安全性传递给数据库的用户上下文是什么?
  • 是否有可能在调用cnn.Open()之前以编程方式检查用户以确认我们有一个真实的用户?

ASP.. NET在连接到数据库时丢失用户上下文

如果你正在使用ORM映射器,例如实体框架或NHibernate(我在NHibernate中经历过这种情况),这可能会发生。这是因为映射框架使用了Lazy Evaluation:在您请求之前,它不会从数据库中获取所有数据。例如,如果您正在获取一个对象列表,其中每个对象都包含另一个对象列表(例如,Customer包含一个Invoice列表),则在您实际使用Invoice对象之前,它不会获取Invoice对象。

如果你在绑定到aspx控件之前不使用它们,并且你在aspx页面中这样做(而不是在例如PageLoad事件中),那么aspx页面的生命周期意味着它会在你的代码运行后查看子列表,并且你正在做的任何模拟已经结束-这是在IIS帐户下。

您可以通过防止惰性求值(通常不是一个好主意)或确保在您的模拟帐户下触摸您需要页面在代码中使用的每个列表来防止这种情况发生。

for each (Customer c in customers)
{
    int i = c.Invoices.Count; // make sure that they do get retrieved.
}