Мы пытаемся создать службу WCF, использующую WSHttpBinding, на сервере A, который при вызове принимает учетные данные вызывающего его устройства и записывает файл на другой сервер. (Ради этого вопроса мы будем называть этот Сервер B, хотя это может быть любой сервер, к которому у вызывающего абонента есть доступ).
Когда мы вызываем это из разработки P C (с обслуживанием и вызывающей стороной на одном P C) или из запланированной задачи на сервере A, этот процесс работает нормально, но когда мы вызываем его из P C клиента мы получаем сообщение «Доступ к пути [путь к файлу назначения] запрещен». Вероятно, это проблема «двойного прыжка».
За последние несколько недель (кажется, месяцы) мы провели некоторое исследование по этому вопросу, но ничто не предложило, чтобы решить проблему, это не помогает, что есть очень мало недавней информации или любой рабочий пример, который использует несколько компьютеров. Вот некоторые из веб-страниц (мы прочитали так много постов, что потеряли счет):
https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/delegation-and-impersonation-with-wcf
https://social.msdn.microsoft.com/Forums/office/en-US/1b65554b-f39e-4d51-be30-828d2f443067/how-to-implement-delegation-in-wcf-service?forum=wcf
https://social.msdn.microsoft.com/Forums/vstudio/en-US/b9ba685f-01c1-439b-9a18-6f9f45d04bf2/impersonated-id-is-not-being-used-in-database-access?forum=wcf
http://geekswithblogs.net/manesh/archive/2009/04/23/setting-up-wcf-to-impersonate-client-credentials.aspx
Настройка WCF служба (Web.config) - HttpsGetEnabled, HttpsGetUrl
https://www.codeproject.com/Articles/38979/How-to-enable-multi-hop-impersonation-using-constr
WCF и передача windows учетных данных
Часть проблемы заключается в том, что мы не уверены, где находится проблема (в коде, веб-конфигурации, на сервере, сайте IIS, пуле приложений IIS, AD или их комбинации)
Как часть процесса тестирования (код ниже), который записывает журнал, некоторые вещи, которые мы обнаружили, не имеют смысла:
- При проверке ServiceSecurityContext.Current.WindowsIdentity.ImpersonationУровень его возвращает «Олицетворение» - если наше понимание правильно, это должно быть делегирование.
- При проверке ServiceSecurityContext.Current.PrimaryIdentity.AuthenticationType он возвращает «NTLM», несмотря на то, что веб-конфигурация отключает это
- В ряде веб-сообщений упоминается, что мы должны отключить " Анонимная аутентификация ”, но каждый раз, когда мы делаем это, мы получаем следующую ошибку
Схемы аутентификации, настроенные на хосте (« IntegratedWindowsAuthentication »), не допускают тех, которые настроены на привязке« WSHttpBinding »(« Аноним ») Убедитесь, что для SecurityMode установлено значение Transport или TransportCredentialOnly. Кроме того, это можно решить путем изменения схем проверки подлинности для этого приложения с помощью инструмента управления IIS через свойство ServiceHost.Authentication.AuthenticationSchemes в файле конфигурации приложения на путем обновления свойства ClientCredentialType в привязке или путем настройки свойства AuthenticationScheme в HttpTransportBindingElement.
Однако, когда мы пытаемся включить режим безопасности транспорта, мы получаем
Не удалось найти базовый адрес, который соответствует схеме https для конечной точки с привязкой WSHttpBinding. Схемы зарегистрированных базовых адресов: [http].
Телефонный код (на P C)
public StringBuilder Messages { get; private set; }
private void cmdReadFolder_Click(object sender, EventArgs e)
{
Messages.AppendLine("Attempting to read folder location " + txtRemoteLoc.Text + " " + DateTime.Now.ToString());
try
{
DelegationService.ControllerClient tester = new DelegationService.ControllerClient();
tester.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Delegation;
List<string> fileListings = new List<string>();
fileListings = tester.ReadFolder(txtRemoteLoc.Text);
Messages.AppendLine("Transfer returns a list of " + fileListings.Count() + " files");
foreach (string file in fileListings)
{
lsvFiles.Items.Add(file);
}
}
catch (Exception ex)
{
Messages.AppendLine("An error has occured in cmdReadFolder_Click");
Messages.AppendLine("Error: " + ex.Message);
}
finally
{
Messages.AppendLine("cmdReadFolder_Click ends " + DateTime.Now.ToString());
MessageBox.Show(Messages.ToString());
}
}
Интерфейс
using System.Collections.Generic;
using System.ServiceModel;
namespace DelegationTest
{
[ServiceContract]
public interface ITransfer
{
[OperationContract]
List<string> ReadLocation(string location);
[OperationContract]
string Upload(byte[] file, string filename, string toLocation);
}
}
a "делает" function
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public List<string> ReadLocation(string location)
{
List<string> matchedFiles = new List<string>();
try
{
using (ServiceSecurityContext.Current.WindowsIdentity.Impersonate())
{
matchedFiles = System.IO.Directory.GetFiles(location).ToList();
}
}
catch (Exception ex)
{
string msg = "****Error Windows ReadLocation - Error message: " + ex.Message;
if (ex.InnerException != null)
msg += "\nInner error Message: " + ex.InnerException.Message;
throw (ex);
}
return matchedFiles;
}
Web Config (некоторые попытки были закомментированы и оставлены в том, что мы пробовали)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="DelegationTest.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<system.web>
<compilation debug="true" />
<authentication mode="Windows" />
<identity impersonate="false" />
<authorization>
<deny users="?"/>
<allow users="*" />
</authorization>
<customErrors mode="Off" />
</system.web>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="ControlerBind" sendTimeout="00:10:00" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="16" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="8192" />
<reliableSession enabled="true" />
<security mode="Message">
<message clientCredentialType="Windows" />
</security>
<!-- <security mode="Transport">
<transport clientCredentialType="Windows" />
</security> -->
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="DelegationTest.Controller">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="ControlerBind" contract="DelegationTest.IController">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" name="MexControlerBind" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://[ServerA]/DelegationTest/DelegationTest.Controller.svc" />
<add baseAddress="https://[ServerA]/DelegationTest/DelegationTest.Controller.svc" />
</baseAddresses>
</host>
</service>
<service name="DelegationTest.Transfer">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="ControlerBind" contract="DelegationTest.ITransfer">
<identity>
<!-- <dns value="localhost" /> -->
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" name="MexControlerBind" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://[ServerA]/DelegationTest/DelegationTest.Transfer.svc" />
<add baseAddress="https://[ServerA]/DelegationTest/DelegationTest.Transfer.svc" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="behaviiorTest">
<clientCredentials>
<windows allowNtlm="false" allowedImpersonationLevel="Delegation" />
<httpDigest impersonationLevel="Delegation" />
</clientCredentials>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="True" />
<serviceAuthorization impersonateCallerForAllOperations="true" />
<!-- <serviceAuthenticationManager authenticationSchemes="IntegratedWindowsAuthentication"/> -->
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Извините за длинный вопрос
Спасибо За вашу помощь заранее