У меня есть служба WCF, работающая локально, и клиент, работающий удаленно. Я сопоставил привязки с обеих сторон:
<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.Name, если они доступны.
При запуске клиента на той же машине, что и сервер, транспортный режим работает нормально, и доступны все три имени удостоверения. Однако при подключении к моей локальной машине с удаленного хоста (проверено на хостах как в одном, так и в разных доменах) я получаю ужасное сообщение «Сервер отклонил учетные данные клиента».
Если я изменю привязку на:
<binding name="TcpBindingConfiguration_1">
<reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
<security mode="None"/>
</binding>
соединение установлено, и фиктивный метод не возвращает ни одного из имен (как я и предполагал).
Может ли кто-нибудь поделиться своей конфигурацией включения проверки подлинности Windows на разных хостах (а иногда и в разных доверенных доменах) с использованием привязки net.tcp? Я видел множество примеров, когда просто говорилось, что для режима безопасности установлено значение «Нет», и это хорошо, но я все же хочу определить, кто звонит.
Так что же дальше? Заставить режим = «Транспорт» работать? Использовать режим = «Нет» и реализовать другой тип авторизации? Перейти на другую привязку, которая успешно использует проверку подлинности Windows?
Приносим извинения, если на этот вопрос был дан ответ в другом месте; Я просто не могу найти где-нибудь, где на него был бы дан окончательный ответ.
Обновление: это код, который я сейчас использую для создания своего клиента:
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(), похоже, работает (по крайней мере, локально).