«Отказано в доступе» при попытке подключения к удаленному серверу IIS - C # - PullRequest
2 голосов
/ 12 марта 2009

При получении подключения к удаленному серверу IIS 6 из приложения C #, работающего под управлением IIS 5.1, я получаю COMException «Access Deined».

Есть идеи? У меня все те же проблемы с оригинальными вопросами.

Обновление - 4/1/09

Я нашел это решение (http://www.codeproject.com/KB/cs/Start_Stop_IIS_Website.aspx), которое состоит из оконного приложения, соединяющегося с сервером IIS для запуска и остановки веб-сайтов. Я могу запустить его на своей рабочей станции и подключиться к серверу IIS.

Тьфу ... почему я могу запустить это отдельное приложение, но не мое приложение ASP.NET?

Оригинал

Я получаю исключение COMException «Отказано в доступе» при попытке подключиться к IIS с удаленного компьютера с помощью метода DirectoryEntry.Exist, чтобы проверить, действителен ли сервер IIS.

string path = string.Format("IIS://{0}/W3SVC", server);

if(DirectoryEntry.Exist(path))
{
    //do something is valid....
}

Я являюсь членом группы активных каталогов, которая была добавлена ​​в группы администраторов на сервер IIS, к которому я пытаюсь подключиться.

Кто-нибудь сталкивался с этой проблемой и знает, как ее решить?

ОБНОВЛЕНИЕ:

@ Kev - это приложение ASP.NET. Также я могу подключиться без имени пользователя и пароля к удаленному серверу через IIS6 Manager.

@ Chris - я пытаюсь подключиться к удаленному серверу, чтобы отобразить количество виртуальных каталогов и определить версию .NET Framework для каждого каталога. См. этот ТАК вопрос.

@ dautzenb - мое приложение ASP.NET работает под управлением IIS 5.1, пытаясь подключиться к серверу IIS 6. Я вижу аудит ошибок в журнале безопасности моей локальной учетной записи ASPNET на удаленном сервере. Когда я пытаюсь отладить приложение, я работаю под своей учетной записью домена и все равно получаю, что в доступе отказано.

ОБНОВЛЕНИЕ 2:

@ Kev - мне удалось установить создание объекта DirectoryEntry с использованием следующей перегрузки:

public DirectoryEntry
(    
    string path,    
    string username,    
    string password
)

Но все свойства содержат «сгенерированное исключение типа« System.Runtime.InteropServices.COMException », пока я отлаживаю приложение.

Кроме того, для свойства AuthenticationType установлено значение Безопасный.

ОБНОВЛЕНИЕ 3:

Следующие две записи аудита сбоев были в журнале событий безопасности удаленного сервера IIS каждый раз, когда я пытался установить соединение:

Первое событие:

Категория события: вход в аккаунт
Код события: 680
Журнал попытки: MICROSOFT_AUTHENTICATION_PACKAGE_V1_0
Вход в систему: ASPNET
Рабочая станция источника:
Код ошибки: 0xC0000234

Второе событие:

Категория события: вход / выход
Код события: 529
Ошибка входа:
Причина: неизвестное имя пользователя или неверный пароль
Имя пользователя: ASPNET
Домен: (MyDomain)
Тип входа: 3
Процесс входа в систему: NtLmSsp
Пакет аутентификации: NTLM
Имя рабочей станции: (MyWorkstationId)
Имя пользователя звонящего: -
Домен вызывающего абонента: -
Идентификатор входящего звонка: -
Идентификатор вызывающего процесса: -
Транзитные услуги: -
Адрес исходной сети: 10.12.13.35
Исходный порт: 1708

Олицетворение имеет значение true, а имя пользователя и пароль не заполнены. Он использует учетную запись ASPNET на удаленном сервере IIS.

Ответы [ 8 ]

2 голосов
/ 04 мая 2009

Если это проблема с идентификацией, вы можете попробовать настроить приложение IIS 5.1 на использование Встроенная проверка подлинности Windows , а затем добавить следующее в ваш файл web.config на своем веб-сайте IIS5.1 в системе. веб для включения олицетворения .

<identity impersonate="true"/>
<authentication mode="Windows" />
1 голос
/ 04 августа 2009

Похоже, что это проблема двойного прыжка. Если вы олицетворяете текущего пользователя веб-сайта, использующего NTLM, это олицетворение действует только на этом сервере (в данном случае на вашем сервере IIS 5.1). Если вы попытаетесь подключиться к другому серверу с помощью веб-сайта, у вас действительно возникнут проблемы, поскольку он не сможет передать токен другому серверу, который использовался во время олицетворения. То же самое верно, если вы отлаживаете свой сайт через свою машину, переходя к другой коробке. Ваш локальный компьютер аутентифицирует вас, но не может выдать себя за другого сервера.

Все решения, которые я использовал в прошлом, требуют от вас жесткого кода пула приложений, чтобы использовать учетную запись, у которой есть разрешения, установить анноним. учетной записи домена с разрешениями на другом компьютере или используйте службу Windows, работающую на компьютере IIS 5.1, под учетной записью домена для подключения к другому серверу.

Если вы используете Kerberos, это не будет применяться, но AD по умолчанию использует NTLM.

1 голос
/ 12 марта 2009

Поскольку это приложение ASP.NET, оно работает в пуле приложений IIS. Этот пул приложений запускается с использованием определенного пользователя («Локальная система», «Сетевая служба» или другой пользователь).

Достаточно ли у этого пользователя прав для подключения к удаленному серверу?

См. MSDN для получения дополнительной информации.

0 голосов
/ 14 августа 2009

Я полагаю, что DirectoryEntry.Exists молча игнорирует все предоставленные учетные данные и использует права аутентифицированного пользователя. Это похоже на поведение, которое вы описали. Для работы с AD мы никогда не используем его по этой причине.

0 голосов
/ 11 августа 2009

Если это действительно двойная проблема NTLM, вы можете использовать утилиту SETSPN для создания именованных экземпляров субъекта службы для ваших целевых серверов IIS.

Затем вы можете зайти в Active Directory и затем разрешить объекту компьютера (в основном принципам NETWORK SERVICE или LOCAL SERVICE) делегировать свои учетные данные правильно зарегистрированному SPN.

Тогда вы могли бы прыгать-хоп-хоп повсюду! Но будьте осторожны! Люди могут поранить себя острыми острыми предметами, когда вы включите двойной прыжок!

Хорошие статьи для чтения в КБ:

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

0 голосов
/ 05 апреля 2009

Когда у меня возникла эта проблема, я обнаружил, что простая аутентификация себя на общем файловом ресурсе Windows решила проблему. Из опыта я думаю, что WMI / ADSI / COM не имеет большой поддержки для пользователей, которые еще не прошли проверку подлинности. Я считаю, что эта проблема возникает, когда вы не связаны с доменом Windows.

0 голосов
/ 12 марта 2009

В данный момент я немного озадачен тем, почему вы не можете заставить это работать. Есть временная работа, которую вы можете попробовать. При создании экземпляра объекта DirectoryEntry вы можете использовать одну из следующих перегрузок конструктора:

public DirectoryEntry(
    string path,
    string username,
    string password
)

Документировано по адресу: MSDN: Конструктор DirectoryEntry (строка, строка, строка)

... или ...

public DirectoryEntry(
    string path,
    string username,
    string password,
    AuthenticationTypes authenticationType
)

Документировано по адресу: MSDN: Конструктор DirectoryEntry (String, String, String, AuthenticationTypes)

По мере того, как это происходит, я создаю тестовую среду AD на своем виртуальном сервере, чтобы новый проект делал подобные вещи. Когда я его запустлю и запустлю, я поиграю, чтобы посмотреть, смогу ли я воспроизвести проблему, с которой вы столкнулись. А пока сообщите нам, что произойдет, если вы попробуете эти перегрузки конструктора, указанные выше.

Обновление (в ответ на комментарий Майклза):

По причинам, которые уклоняются от меня сейчас, мы не можем использовать DirectoryEntry.Exists() в конкретном сценарии, есть фрагмент кода, который время от времени вызывается в одном из наших приложений:

public static bool MetabasePathExists(string metabasePath)
{
  try
  {
    using(DirectoryEntry site = new DirectoryEntry(metabasePath))
    {
      if(site.Name != String.Empty)
      {
        return true;
      }
      return false;
    }
  }
  catch(COMException ex)
  {
    if(ex.Message.StartsWith("The system cannot find the path specified"))
    {
      return false;
    }
    LogError(ex, String.Format("metabasePath={0}", metabasePath));
    throw;
  }
  catch(Exception ex)
  {
    LogError(ex, String.Format("metabasePath={0}", metabasePath));
    throw;
  }
}

Вы можете заменить конструктор одним из приведенных выше. По общему признанию это - удар в темноте:).

0 голосов
/ 12 марта 2009

Где именно ты тоже пытаешься читать? Это по тому же пути, что и ваше приложение?

...