У нас есть самообслуживаемая служба WCF, которая размещает контент по HTTP и хочет иметь возможность поддерживать единую регистрацию с помощью Windows/AD. В идеале это будет поддерживать IE, Firefox и Chrome.Самостоятельный сервер WCF с SSO
Я построил следующую примерную службу, которая возвращает некоторый простой текст через HTTP. Примечание: в производственной версии этого мы используем SSL, но я отключил это ниже, чтобы сделать выборку менее тонкой.
Мы установили HttpSecurityMode для TransportCredentialOnly, а затем ClientCredentialType в HttpClientCredentialType.Windows, который, я считаю, будет использовать Kerberos.
Если я использую «NTLM» вместо «Windows», это похоже на работу, но я понимаю, что использование NTLM не рекомендуется, и оно ломается, если у нас есть обратный прокси-сервер, сидящий перед нашим сервисом.
Когда мы запускаем следующий код и подключаемся в IE 10, мы получаем запрос на получение учетных данных Windows, но после ввода этих данных мы просто получаем HTTP 400, и я не ударяю никаких точек останова в моем методе «Get». В идеале мы должны увидеть ответ «Привет, [Domain \ User]!» но мы не делаем это так далеко.
Наши тестовые машины (клиент и сервер) являются частью одного и того же домена Windows. Я запускаю службу как локальный администратор, но не администратор домена (если это имеет значение).
Мы будем признательны за любую помощь!
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Web;
using System.Text;
namespace WindowsAuthService
{
[ServiceContract]
public interface ITestService
{
[OperationContract]
[WebGet(UriTemplate = "{*path}")]
Stream Get(string path);
}
public class TestService : ITestService
{
public Stream Get(string path)
{
WebOperationContext.Current.OutgoingResponse.Headers.Add(HttpResponseHeader.ContentType, "text/plain");
if (OperationContext.Current.ServiceSecurityContext == null)
return new MemoryStream(Encoding.ASCII.GetBytes(String.Format("Hello, {0}!", "Anonymous Stranger")));
else
return new MemoryStream(Encoding.ASCII.GetBytes(String.Format("Hello, {0}!", OperationContext.Current.ServiceSecurityContext.WindowsIdentity.Name)));
}
}
class Program
{
private const string URL = "http://mymachine.mydomain:7777";
static void Main(string[] args)
{
WebServiceHost serviceHost = new WebServiceHost(new TestService());
foreach (IServiceBehavior attr in serviceHost.Description.Behaviors)
{
if (attr is ServiceBehaviorAttribute)
{
ServiceBehaviorAttribute serviceAttr = (ServiceBehaviorAttribute)attr;
serviceAttr.InstanceContextMode = InstanceContextMode.Single;
serviceAttr.ConcurrencyMode = ConcurrencyMode.Multiple;
}
}
WebHttpBinding binding = new WebHttpBinding(WebHttpSecurityMode.TransportCredentialOnly);
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
ServiceEndpoint serviceEndpoint = serviceHost.AddServiceEndpoint(typeof (ITestService), binding, URL);
serviceEndpoint.Behaviors.Add(new WebHttpBehavior());
Console.WriteLine("Service Listening @ " + URL);
serviceHost.Open();
Console.WriteLine("[ Press Enter to Quit ]");
Console.ReadLine();
}
}
}
У меня нет настройки прокси. Я настроил «Автоматически обнаруживать локальную интрасеть», чтобы включить мой сервер, и это исправить. Знаете ли вы, если у вас есть какие-либо шансы на работу в Firefox или Chrome? –
Да, должен работать на окнах - от руки он работает в Chrome. Но удача на других не-ОС Windows. – YK1
Я говорил слишком рано. HttpClientCredentialType.Windows работает только на моей машине. Как только я пытаюсь использовать другую машину, она не работает вообще. Однако предложение о добавлении сервера в «Локальный интрасеть» упростило аутентификацию NTLM без каких-либо запросов в IE и Chrome. К сожалению, ограничение без прокси-сервера в NTLM по-прежнему является проблемой. Я явно пропускаю что-то с HttpClientCredentialType.Windows ... –