Мы разрабатываем много служб WCF, которые размещены в IIS. (IIS 6.0 работает на Windows Server 2003 с пакетом обновления 2). Эти сервисы настроены для 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 при раскрутке машины.
Теперь я знаю проблему с именем участника-службы, так как у нас на одном веб-сайте размещено несколько служб (обычно это веб-сайт по умолчанию), мы можем создать только 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;
}