Как использовать имена компьютеров в службах 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;
        }

person Patrick Escarcega    schedule 06.08.2010    source источник


Ответы (3)


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

person Patrick Escarcega    schedule 02.09.2011

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

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

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

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

person atconway    schedule 06.08.2010

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

person felickz    schedule 12.02.2013