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

C# ASP.NET在连接到数据库时丢失用户上下文,c#,asp.net,sql-server,authentication,ado.net,C#,Asp.net,Sql Server,Authentication,Ado.net,在ASP.NET中,我们有一个应用程序,它使用基本身份验证和ASP.NET模拟提示用户输入他们的广告凭据 然后,应用程序使用以下连接字符串连接到SQL Server SqlClient.SqlConnection cnn=newsqlclient.SqlConnection(); cnn.ConnectionString= “Server=“+MenuServer+”;“+ “Database=“+MenuDatabase+”;“+ “受信任的连接=是;” “池=假;”; cnn.Open();

在ASP.NET中,我们有一个应用程序,它使用基本身份验证和ASP.NET模拟提示用户输入他们的广告凭据

然后,应用程序使用以下连接字符串连接到SQL Server

SqlClient.SqlConnection cnn=newsqlclient.SqlConnection();
cnn.ConnectionString=
“Server=“+MenuServer+”;“+
“Database=“+MenuDatabase+”;“+
“受信任的连接=是;”
“池=假;”;
cnn.Open();
99%的情况下,这会很好地传递给用户上下文,但偶尔会从SQL Server中得到以下错误:

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

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

string userName=Environment.userName;
问题

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

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

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

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

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

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

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

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

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

西蒙,谢谢,但我认为这不是问题所在。对于1,我们只是使用.NET业务库作为我们的ORM层,所以它不会懒散地评估任何东西。对于2,我们在连接上调用
Open
时会立即抛出错误,并且我们总是在应用程序启动时(当我们看到它时)在初始化会话时立即看到此错误。在进行数据库调用之前,可能存在一些奇怪的竞争条件来建立经过身份验证的用户,但简单地立即调用不会改变任何事情。当您进行连接时,System.Security.Principal.WindowsIdentity.GetCurrent().Name会返回什么。Open()?该错误只会在野外偶尔出现,但我将添加以下变量的日志记录,以查看正在填充哪些变量:
Environment.UserName
System.Web.HttpContext.Current.User.Identity.IsAuthenticated
System.Web.HttpContext.Current.User.Identity.Name
System.Web.Security.Membership.GetUser().UserName
System.Security.Principal.WindowsIdentity.GetCurrent().Name
。我问这个问题是想看看是否有人提前知道哪个身份可能会传递给SQL Server。我认为它使用WindowsIdentity.CurrentUser,但可能是错误的。祝你好运让我们知道会发生什么!西蒙,谢谢,但我认为这不是问题所在。对于1,我们只是使用.NET业务库作为我们的ORM层,所以它不会懒散地评估任何东西。对于2,我们在连接上调用
Open
时会立即抛出错误,并且我们总是在应用程序启动时(当我们看到它时)在初始化会话时立即看到此错误。在进行数据库调用之前,可能存在一些奇怪的竞争条件来建立经过身份验证的用户,但简单地立即调用不会改变任何事情。当您进行连接时,System.Security.Principal.WindowsIdentity.GetCurrent().Name会返回什么。Open()?该错误只会在野外偶尔出现,但我将添加以下变量的日志记录,以查看正在填充哪些变量:
Environment.UserName
System.Web.HttpContext.Current.User.Identity.IsAuthenticated
System.Web.HttpContext.Current.User.Identity.Name
System.Web.Security.Membership.GetUser().UserName
System.Security.Principal.WindowsIdentity.GetCurrent().Name
。我问这个问题是想看看是否有人提前知道哪个身份可能会传递给SQL Server。我认为它使用WindowsIdentity.CurrentUser,但可能是错误的。祝你好运让我们知道会发生什么!