У меня есть приложение ASP.NET 4.0, работающее в Windows 7/IIS 7.5 в пуле приложений "ASP.NET v4.0 Classic", который настроен для работы в качестве сетевой службы. Приложение имеет обработчик Application_EndRequest
, который подключается к локальному экземпляру SQL Server. Строка подключения SQL указывает Integrated Security=SSPI
. У Web.config нет <identity impersonate="true" />
.
Когда я перейду к http://localhost/TestSite/
, выдается следующее исключение:
System.Data.SqlClient.SqlException (0x80131904): Login failed for user 'NT AUTHORITY\IUSR'.
...
at System.Data.SqlClient.SqlConnection.Open()
at Global.Application_EndRequest(Object sender, EventArgs e)
Это исключение не возникает, когда я просматриваю http://localhost/TestSite/default.aspx
(документ по умолчанию, настроенный в IIS) или любую другую страницу .aspx; в тех случаях приложение правильно подключается к SQL Server как "NT AUTHORITY\NETWORK SERVICE", которое является допустимым логином.
Почему ASP.NET олицетворяет "NT AUTHORITY\IUSR" в EndRequest, даже если олицетворение отключено? Это ошибка в ASP.NET?
Следующий файл Global.asax.cs демонстрирует проблему:
public class Global : HttpApplication
{
public Global()
{
this.BeginRequest += delegate { Log("BeginRequest"); };
this.PreRequestHandlerExecute += delegate { Log("PreRequestHandlerExecute"); };
this.PostRequestHandlerExecute += delegate { Log("PostRequestHandlerExecute"); };
this.EndRequest += delegate { Log("EndRequest"); };
}
protected void Application_EndRequest(Object sender, EventArgs e)
{
try
{
using (SqlConnection connection = new SqlConnection("Server=.;Integrated Security=SSPI"))
{
connection.Open();
}
}
catch (Exception ex)
{
Trace.WriteLine(ex);
}
}
private static void Log(string eventName)
{
HttpContext context = HttpContext.Current;
Type impersonationContextType = typeof(HttpContext).Assembly.GetType("System.Web.ImpersonationContext", true);
Trace.WriteLine(string.Format("ThreadId={0} {1} {2} Impersonating={3}",
Thread.CurrentThread.ManagedThreadId,
context.Request.Url,
eventName,
impersonationContextType.InvokeMember("CurrentThreadTokenExists", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.GetProperty, null, context, null)));
}
}
Здесь вывод трассировки:
ThreadId=3 http://localhost/TestSite/ BeginRequest Impersonating=False
ThreadId=3 http://localhost/TestSite/ PreRequestHandlerExecute Impersonating=False
ThreadId=7 http://localhost/TestSite/default.aspx BeginRequest Impersonating=False
ThreadId=7 http://localhost/TestSite/default.aspx PreRequestHandlerExecute Impersonating=False
ThreadId=7 http://localhost/TestSite/default.aspx PostRequestHandlerExecute Impersonating=False
ThreadId=7 http://localhost/TestSite/default.aspx EndRequest Impersonating=False
ThreadId=7 http://localhost/TestSite/ PostRequestHandlerExecute Impersonating=True
ThreadId=7 http://localhost/TestSite/ EndRequest Impersonating=True
System.Data.SqlClient.SqlException (0x80131904): Login failed for user 'NT AUTHORITY\IUSR'.
...
at System.Data.SqlClient.SqlConnection.Open()
at Global.Application_EndRequest(Object sender, EventArgs e)
Обратите внимание, что запрос TestSite/
(который отображается на DefaultHttpHandler
), кажется, порождает вложенный запрос на TestSite/default.aspx
(который отображается на ASP.default_aspx
). После завершения ASP.NET обработки TestSite/default.aspx
он выдает "NT AUTHORITY\IUSR", когда он возобновляет обработку запроса до TestSite/
.
ОБНОВЛЕНИЕ: Я отправил эту проблему в Microsoft Connect.