Подтвердить что ты не робот

ASP.NET олицетворяет NT AUTHORITY\IUSR, но олицетворение отключено. Ошибка ASP.NET?

У меня есть приложение 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.

4b9b3361

Ответ 1

Скорее всего, настройки для вашего сервера, сайта или приложения установлены так, что режим "Анонимная аутентификация" вызывает обращение к запросам страниц в качестве пользователя IUSR. Не имеет значения, что ваше приложение не запрашивает олицетворения; IIS заставляет это. (Кстати, "олицетворение" - это общий термин в Windows-land для принятия других учетных данных пользователя. Это не относится к ASP.NET.)

Немного фона:

По соображениям безопасности IIS позволяет вашему серверу вводить "анонимные" и "аутентифицированные" запросы под разными учетными данными системы.

Теперь, в IIS 7.5, если вы используете анонимную аутентификацию и аутентификацию форм (что типично), перед тем, как пользователь вашего сайта войдет в систему через Forms, он считает вашего пользователя "анонимным". После того, как ваш пользователь войдет в систему с помощью Forms Auth, он считает, что ваш пользователь "аутентифицирован".

Я впервые обнаружил, что это поведение запутывает, потому что это изменение от IIS 6.0, которое не было известно о Forms auth, и считало, что все пользователи, прошедшие проверку подлинности с помощью форм, являются анонимными!

Если вы хотите, вы можете изменить идентификатор, под которым отображаются анонимные запросы. Мои предпочтения (и это звучит так же, как и у вас) - это то, что они запускаются под теми же системными учетными данными, что и мой пул приложений на сайте. Чтобы сделать IIS, выполните следующие действия:

  • Откройте диспетчер IIS (inetmgr)
  • На панели "Подключения" перейдите на сайт node и выберите его
  • На правой панели в группе "IIS" дважды щелкните значок "Идентификация".
  • Щелкните правой кнопкой мыши "Анонимная аутентификация" и выберите "Изменить..." в контекстном меню.
  • В диалоговом окне всплывающего окна выберите значок "Идентификатор пула приложений" .
  • Нажмите "ОК".

Шаг 5 также сначала смутил меня, потому что я думал, что "идентификатор пула приложений" означает "псевдо-учетная запись пула приложений" (еще одна новая функция в IIS 7.5). Разумеется, это означает, что "та же самая учетная запись, для которой настроен запуск приложения, независимо от того, что это такое."

Если вы хотите, чтобы это поведение было по умолчанию для всех ваших сайтов на этом сервере или даже просто для одного приложения на определенном сайте, вы также можете настроить параметры проверки подлинности на этих уровнях. Просто выберите node, который вы хотите настроить на панели "Подключения", затем повторите шаги 3-6.

Ответ 2

Почему приложение попытается войти в систему как "NT AUTHORITY\IUSR", даже если приложение (возможно) не использует олицетворение?

Если вы делаете

<identity impersonate="true"/>

он будет выдавать себя за зарегистрированного пользователя

Если вы делаете

<identity impersonate="true" userName="contoso\Jane" password="pass"/>

он выдаст себя за пользователя, установленного выше.

Но если вы вообще не олицетворяете себя и не используете аутентификацию Windows, было бы разумно, что она использует системную учетную запись по умолчанию.

Я не знаю, почему он делает первую попытку как IUSR, а затем автоматически переключается на NETWORK SERVICE при последующих запросах. Но я знаю, что когда вы переходите с одного сервера на другой, аутентификаторы пула приложений НЕ используются. Если вы не установили олицетворенного пользователя, как показано ниже, NETWORK SERVICE - это учетная запись по умолчанию, которая используется для извлечения ресурсов вне сервера.

    <connectionStrings>
        <add name="myConnectionString" connectionString="Data Source=MyServerName;Initial Catalog=MyDataBaseName;Integrated Security=True;"
          providerName="System.Data.SqlClient" />
      </connectionStrings>

<identity impersonate="true" userName="contoso\Jane" password="pass"/>