Мы разрабатываем множество служб 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;
}