Как использовать имена компьютеров в службах WCF с REST с проверкой подлинности Windows

Мы разрабатываем много служб WCF, которые размещены в IIS. (IIS 6.0 работает на Windows Server 2003 SP2). Эти сервисы настроены для REST. Для среды (DEV, CERT, PROD) у нас обычно есть много служб на сервер IIS. Каждая служба имеет свою учетную запись, которая назначается через пул приложений.

Это работает нормально, но если мы включим проверку подлинности Windows в виртуальном каталоге (чтобы разрешить передачу пользовательского контекста, а не для олицетворения или делегирования), мы получим ошибки безопасности в определенных случаях. Если мы подключаемся к сервису в коде C# с помощью ServiceEndpoint, он работает, однако, когда мы подключаемся к сервисам через браузер или не код Wcf (например, HttpWebRequest, java и др.), Мы получаем ошибки безопасности.

Если я изменю аутентификацию в IIS с Negotiate, NTLM на NTLM, то это сработает. На самом деле происходит то, что мы отключаем Kerberos, и поскольку эти службы общаются с другими серверами в сети, у нас начинают возникать другие проблемы, когда службы не могут подключаться к удаленным серверам (обычно к SQL Server).

Теперь вот странная часть, если мы дадим машине псевдоним DNS (запись CNAME) и используем URL с псевдонимом, который работает. например

http://dnsalias/service/myservice.svc/foo WORKS!
but
http://machinename/service/myservice.svc/foo  FAILS :(

Мы не можем дать псевдонимам DNS всех этих машин (это было нашим решением на данный момент), потому что мы начинаем широко использовать виртуальные машины и раскручиваем их вверх и вниз. Таким образом, у нас есть только имена компьютеров, мы не хотим запускать сценарии псевдонимов DNS при раскрутке машины.

Однако теперь я знаю проблему с SPN, поскольку у нас на одном веб-сайте размещено несколько служб (обычно это веб-сайт по умолчанию), поэтому мы можем создать только 1 имя участника службы на сервер / учетную запись. Поскольку мы размещаем несколько служб для каждого сервера, каждый из которых сопоставлен с собственной учетной записью, это не решение.

setspn -a HTTP//WCFServer.domain.com customDomainAccount

Еще одна проблема: мы не определяем конечные точки в конфигурационных файлах, только в коде, вот код для получения привязки REST.

protected internal static Binding GetWebHttpBinding()
        {
            // Create a new binding with Authentication enabled
            var binding = new WebHttpBinding(WebHttpSecurityMode.TransportCredentialOnly);

            // Set defaults
            SetTimeouts(binding);
            SetReaderQuotas(binding.ReaderQuotas);
            binding.MaxReceivedMessageSize = MaxReceivedMessageSize;
            binding.MaxBufferSize = 65536;

            // Set the Credential type to Windows to allow single sign-on
            binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;

            // Need Streamed Response since Transport security does not allow streamed requests
            binding.TransferMode = TransferMode.StreamedResponse;

            return binding;
        }

3 ответа

Хорошо, намного позже я вернусь с ответом. Для описанной среды единственным ответом является использование аутентификации NTLM. Это было подтверждено звонком в службу поддержки Microsoft.

Я понял, что имя машины уже является записью DNS. Необработанное имя / или имя машины на самом деле является ее IP-адресом. Итак, когда вы указываете "имя_машины" в своем URL, которое не работает, не является ли это уже записью DNS? Если вы пингуете 'machinename', какой IP-адрес показывает ответ на пинг; это должен быть IP машины.

Для меня это звучит так, как будто вы создаете поиск DNS для поиска DNS. Можете немного прояснить это?

Я могу подтвердить, что магия случается и со мной, как только я получу DNS-запрос в домене для определения IP-адреса службы WCF или сайта, с которым я работаю, поэтому я понимаю, откуда вы пришли.

Я не знаю, как выглядит ваш клиентский код, но посмотрите на следующую ссылку, чтобы соответствовать. Вы должны создать сетевые учетные данные перед вызовом службы RESTful. Если вы сделаете это, решит ли это другую проблему с необходимостью разбить Kerberos?

Я также получал аналогичные "ошибки безопасности" с помощью встроенной аутентификации Windows и WebHttpBinding, пытавшейся использовать WebHttpSecurityMode.TransportCredentialOnly.., но мне требовался SSL, поэтому я мог придерживаться WebHttpSecurityMode.Transport при настройке HttpClientCredentialType.Windows.

Другие вопросы по тегам