Доступ запрещен с помощью MSXML - PullRequest
5 голосов
/ 29 июля 2009

У меня есть бэкэнд VB6 для классического сайта ASP. Затем этот VB вызывает веб-сервис на том же сервере, используя MSXML2.XMLHTTP. Это работает на всех наших серверах, кроме одного. Если я настрою сайт веб-службы для принятия анонимного входа, он будет работать, однако, если я включу только встроенную защиту, MSXML возвращает ошибку «Отказано в доступе».

Я использую код из примера здесь.

Set objDom = CreateObject("MSXML2.DOMDocument")
Set objXmlHttp = CreateObject("MSXML2.XMLHTTP")

' Load XML
objDom.async = False
objDom.loadXML XmlBody

' Open the webservice
objXmlHttp.Open "POST", AsmxUrl, False

' Create headings
objXmlHttp.setRequestHeader "Content-Type", "text/xml; charset=utf-8"
objXmlHttp.setRequestHeader "SOAPAction", SoapActionUrl

' Send XML command
objXmlHttp.send objDom.xml

Edit: Следуя совету AnthonyWJones, я опустил контрольный список, и он все еще не работает. Используя Fiddler, он показывает один запрос с ответом 401. На вкладке аутентификации отображается:

No Proxy-Authenticate Header is present.
WWW-Authenticate Header is present: Negotiate
WWW-Authenticate Header is present: NTLM

Хотя я заметил странное поведение. Когда я звоню на сайт, используя учетные данные пользователя, который вошел в удаленный рабочий стол, он будет работать. Я получаю переговоры, вызов, затем 200, и это будет работать. Любые идеи, почему это будет работать, когда пользователь вошел в систему через удаленный рабочий стол, но не в других случаях?

Ответы [ 3 ]

3 голосов
/ 04 декабря 2009

Вероятно, уже слишком поздно отвечать Райану, но у других может быть такая же проблема, поэтому я опубликую это: у меня есть разработчик, который сталкивается с той же проблемой с MSXML2.XMLHTTP. Дело в том, что у меня есть образцы, которые делают это с давних времен, так что я знаю, что использовал для работы, но это не так ... может быть, недавно появившаяся ошибка? Мы полагались на автоматическое обнаружение локальной интрасети с помощью стека WinINET, и тогда этот стек был бы готов интегрировать Windows. Сайт был в списке обхода прокси, который с параметрами по умолчанию помещает его в локальную интрасеть. И действительно, когда вы переходите на сайт и переходите на вкладку «Настройки безопасности», вы видите, что локальная интрасеть подсвечена, поэтому она работает. Тем не менее MSXML2.XMLHTTP по-прежнему не хочет интегрировать Windows ... Если вы не добавляете сайт непосредственно в локальную интрасеть, используя кнопки Сайты / Дополнительно на вкладке Безопасность.

Итак, я пришел к выводу, что в стеке WinINET теперь есть какая-то ошибка, которая обрабатывает автоматически обнаруженные сайты локальной интрасети иначе, чем те, которые непосредственно добавляются в список сайтов. Самое смешное, что когда просматривает на сайте, все работает так, как ожидалось, и Windows Integrated используется автоматически (даже без непосредственного добавления на сайты): это только программный доступ через MSXML2. XMLHTTP, который не работает.

Наконец, это не то, что мы закончили, хотя: вместо этого мы использовали MSXML2.ServerXMLHTTP.6.0. Этот стек (WinHTTP), кажется, делает все правильно, однако есть одна оговорка: он не использует настройки прокси IE по умолчанию, и поэтому у вас есть несколько вариантов - использовать ProxyCfg (для XP и более ранних версий) или NETSH для Vista и позже, чтобы импортировать настройки прокси IE в стек WinHTTP. Недостатком этого является дополнительная настройка на каждом клиентском компьютере (это было полнофункциональное клиентское приложение VB). Вместо этого мы решили поместить следующее перед отправкой:

HTTP.SetProxy 2, "myproxy.mydomain.com", "* .mydomain.com"

Поскольку вы будете заходить на сайт mydomain, вы можете подумать, что вместо этого можете сказать HTTP.SetProxy 0, чтобы обойти прокси, но это не работает. Для стека нужно сказать: «У меня есть прокси, но я обхожу его для своего домена, и, кстати, сайт, на который я собираюсь, находится в этом домене, так что это локальная интрасеть».

3 голосов
/ 29 июля 2009

Я полагаю, что вы полагаетесь на базовый стек WinINET HTTP, чтобы представить учетные данные текущих пользователей на сервер, когда сервер запрашивает их, используя встроенную безопасность Windows.

По умолчанию WinINET сделает это только в том случае, если сервер хоста будет находиться в зоне интрасети. Даже в этом случае возможно, что параметры безопасности зоны интрасети пользователей были изменены, чтобы запретить это.

Попробуйте посетить сайт с помощью браузера на клиентском компьютере, если вы вошли в систему как тот же пользователь, под которым работает ваше приложение VB6. В какой зоне он считает сервер? Если это не Интранет, вам нужно будет добавить хост в список сайтов, принадлежащих к зоне. Пока вы там, откройте настройки безопасности зон и прокрутите вниз до категории «Аутентификация пользователя». Вход в систему должен быть настроен как «Автоматический вход только в зоне интрасети».

Редактировать : Из вашего комментария эти вещи настроены правильно. Несколько вещей, которыми я бы был: -

  1. Убедитесь, что сервер строго настроен на принятие только встроенной защиты Windows.
  2. Проверьте настройки прокси-сервера на машине. Отказано ли в разрешении проблема с прокси-сервером?
  3. Используйте ProgID "MSXML2.XMLHTTP.3.0", чтобы убедиться, что используется правильная версия MSXML dll (некоторые установки сторонних приложений могут повредить реестр, что приведет к использованию более старой версии MSXML).
  4. Установите Fiddler на машину и наблюдайте за http-разговором, когда приложение VB6 пытается выполнить вызов. Есть ли один ответ 401? WinINET не использует учетные данные пользователя? Есть ли 3 401 ответ? WinINET попытался использовать учетные данные текущих пользователей, но они не были приняты сервером.

С этого момента мы попадаем на территорию системного администратора. Например, если трассировка скрипача показывает, что при попытке аутентификации не используется NTLM, то при этом используется аутентификация Kerberos, убедитесь, что на сервере и клиенте установлены часы в течение 5 минут и контроллер домена.

Проверьте журнал событий серверов, сервер не может связаться с контроллером домена.

Разместите простой .htm на сервере с интегрированной защитой только Windows и попытайтесь запустить его из браузера, это удастся?

0 голосов
/ 31 июля 2009

Посмотрев на все, что предложил AnthonyWJones, я обнаружил, что могу использовать обычную аутентификацию, выполнив:

 objXmlHttp.Open "POST", AsmxUrl, False, UserName, Password

Если бы я разрешил интегрированную защиту, он попытался бы договориться, но затем потерпел бы неудачу и 401, но если разрешена только базовая аутентификация, он подключится. Это не мой первый выбор, но это лучший обходной путь, чем предоставление анонимного доступа. Я оставлю это открытым немного дольше, если кто-то может объяснить, как заставить работать интегрированную безопасность, но затем даст AnthonyWJones приемлемый ответ, так как его контрольный список хорош и заставил меня найти этот другой вариант.

Скрипач очень помог в выяснении всего этого.

...