2012-05-23 7 views
2

У меня есть служба WCF, работающая локально, и клиент работает удаленно. Я соответствовал привязок с обеих сторон:WCF Transport Windows Authentication with NET.TCP работает только локально

<binding name="TcpBindingConfiguration_2"> 
    <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" /> 
    <security mode="Transport"> 
    <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"/> 
    <message clientCredentialType="Windows"/> 
    </security> 
</binding> 

У меня есть фиктивный установка метод, который просто возвращает Thread.CurrentPrincipal.Identity.Name, ServiceSecurityContext.Current.WindowsIdentity.Name и OperationContext.Current.ServiceSecurityContext.WindowsIdentity. Имя, если оно доступно.

При запуске клиента на том же компьютере, что и сервер, режим транспорта работает нормально и все три идентификатора доступны. Однако при подключении к локальной машине с удаленного хоста (тестируется на хостах на обоих одинаковых и разных доменах), я получаю ужасное сообщение «Сервер отклонил данные учетных данных клиента».

Если изменить связывание:

<binding name="TcpBindingConfiguration_1"> 
    <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" /> 
    <security mode="None"/> 
</binding> 

соединение выполнено и фиктивный метод не возвращает ни одно из имен (как я бы себе представить).

Может ли кто-нибудь поделиться своей конфигурацией включения проверки подлинности Windows на разных хостах (а иногда и на разных доверенных доменах), используя привязку net.tcp? Я видел множество примеров, которые говорят о том, что для режима безопасности используется None, что все хорошо и хорошо, но я все же хочу определить, кто звонит.

Итак, что дальше? Получить режим = «Транспорт» работает? Использовать режим = «Нет» и реализовать какой-либо другой тип авторизации? Изменить на другую привязку, которая успешно использует проверку подлинности Windows?

Извините, если на это был дан ответ в другом месте; Я просто не могу найти то, на что он окончательно ответил.

Update: Это код, я теперь использую для создания своего клиента:

var endPointAddress = "net.tcp://" + remoteHost + ":8092/Marc/WcfService"; 
EndpointAddress address = new EndpointAddress(new Uri(endPointAddress), EndpointIdentity.CreateSpnIdentity("AppName/" + remoteHost), new AddressHeaderCollection()); 
NetTcpBinding binding = new NetTcpBinding(); 
binding.Security.Mode = SecurityMode.Transport; 
binding.Security.Transport.ProtectionLevel = System.Net.Security.ProtectionLevel.EncryptAndSign; 

using (var remoteService = new RemoteService.GuestServiceClient(binding, address)) 
{ 
    try 
    { 
     MessageBox.Show(remoteService.Hello("Marc")); 
     remoteService.Close(); 
    } 
    catch (Exception ex) 
    { 
     remoteService.Abort(); 
     MessageBox.Show("Error occurred:\n\n" + ex.Source + "\n\n" + ex.Message, "Could not connect to " + remoteHost, MessageBoxButton.OK, MessageBoxImage.Error); 
    } 
} 

RemoteHOST в настоящее время устанавливается на IP-адрес удаленной машины.

Должен ли я использовать каналы и прокси и прочее? Я видел другой код в другом месте, но это простое выполнение GuestServiceClient(), похоже, работает (по крайней мере, локально).

ответ

0

Обычно я настраиваю свои службы WCF в коде, поэтому я не уверен, как это перевести в конфигурационный файл.

Из моих исследований, проведенных в этом году назад, вам необходимо добавить имя участника-службы (SPN) как часть конечной точки клиента. Серверной стороне не нужно было изменять.

В коде это выглядит следующим образом:

string endPointAddress = String.Format("net.tcp://{0}:1111/ServiceName", ServerAddress); 
EndpointAddress address = new EndpointAddress(new Uri(endPointAddress), EndpointIdentity.CreateSpnIdentity("AppName/" + ServerAddress), new AddressHeaderCollection()); 
NetTcpBinding binding = new NetTcpBinding(); 
binding.Security.Mode = SecurityMode.Transport; 

Вторая линия, что добавляет SPN к информации о соединении. В EndpointIdentity.CreateSpnIdentity строка находится в формате AppName/ServerAddress. Часть «AppName» может быть чем угодно, но я рекомендую что-то уникальное для вашего приложения. Я в основном использую формат FQDN (host.domain.com) для адреса.

Опять же, я не уверен, как это переводится в конфигурационный файл. Надеюсь, это поможет вам начать путь по правильному пути.

+0

Я использую код для создания клиента, но configs для создания серверов. Не спрашивайте меня, почему, просто так случилось .. lol .. Все еще не получаю радости, это код, который я использую на клиенте. Используете ли вы каналы или прокси или открываете клиента, как я делаю выше? – Marc

+0

Я выкопаю код, который я сделал для другого проекта, и посмотрю, что я мог пропустить. –