Служба Windows Hosted WCF Service, получающая «Отказано в доступе» при попытке прочитать файл - PullRequest
0 голосов
/ 27 сентября 2011

Я создал службу Windows с единственной целью размещения службы WCF.В службе WCF у меня есть метод, который при обращении к клиенту читает реестр для пути к файлу.Затем метод читает содержимое файла и отправляет обратно содержимое.

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

Я думал, что самым простым решением было изменить учетную запись, под которой работала моя служба Windows.Я изменил учетную запись на ЛОКАЛЬНЫЙ СЕРВИС и СЕТЬ СЕРВИС.Я предоставил полные разрешения безопасности для рассматриваемого каталога для этих учетных данных и все еще не мог прочитать файл!

Моя следующая мысль состояла в том, что эти машины находятся в одном домене, и я мог использовать олицетворение для чтения файла.Я попробовал эту настройку, но теперь мой клиент не может найти мою службу WCF.

Что не так с моей конфигурацией для моей службы, которая мешает мне либо прочитать файл, либо получить доступ к службе?

Вот мой App.config из службы:

<?xml version="1.0"?>
<configuration>
  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="TransportCredWSBinding">
          <security mode="Transport">
            <transport clientCredentialType="Windows" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>

    <services>
      <service name="AMS.CRSS.Service">
        <host>
          <baseAddresses>
            <add baseAddress="https://localhost:8000/CRSS/service"/>
            <add baseAddress="http://localhost:8000/CRSS/service"/>
          </baseAddresses>
        </host>
        <!-- this endpoint is exposed at the base address provided by host: http://localhost:8000/CRSS/service  -->
        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="TransportCredWSBinding" contract="AMS.Core.Services.IService"/>
        <!-- the mex endpoint is exposed at https://localhost:8000/CRSS/service/mex -->
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>

    <!--For debugging purposes set the includeExceptionDetailInFaults attribute to true-->
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="False" httpsHelpPageEnabled="true"/>
          <serviceCredentials>
            <clientCertificate>
              <authentication mapClientCertificateToWindowsAccount="true" />
            </clientCertificate>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>

  </system.serviceModel>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>
</configuration>

Я думаю, что служба WCF работает под другими учетными данными, чем служба Windows, которая является ее хостом.Я здесь не прав?Я полагаю, я мог бы попытаться дать «Все» доступ к папке и посмотреть, работает ли это.

РЕДАКТИРОВАТЬ: Вот код клиента, который я использую для подключения к службе:

public static CRSSClient GetClientInstance(string clientHost)
    {
        UriBuilder ub = new UriBuilder("https", clientHost, 8000);
        ub.Path = "CRSS/service";

        WSHttpBinding binding = new WSHttpBinding();
        binding.Security.Mode = SecurityMode.Transport;
        binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;

        CRSSClient client = new CRSSClient(binding, new EndpointAddress(ub.Uri));
        client.ClientCredentials.Windows.AllowedImpersonationLevel =
            System.Security.Principal.TokenImpersonationLevel.Impersonation;

        return client;
    }

Вот метод, который я вызываю у клиента:

[OperationBehavior(Impersonation = ImpersonationOption.Required)]
    public string ReadCAMConfig()
    {
        string camConfigText = null;
        string camConfigFileLocation = GetCAMConfigLocationFromReistry();

        EventLog.WriteEntry("CRSS", "Reading CAM File: " + camConfigFileLocation + CAM_FILENAME);

        WindowsIdentity identity = ServiceSecurityContext.Current.WindowsIdentity;
        using (identity.Impersonate())
        {
            try
            {
                if (File.Exists(camConfigFileLocation + CAM_FILENAME))
                {
                    camConfigText = File.ReadAllText(camConfigFileLocation + CAM_FILENAME);
                }
            }
            catch (Exception e)
            {
                EventLog.WriteEntry("CRSS", e.ToOutputString(), EventLogEntryType.Error);
            }
        }

        return camConfigText;
    }

1 Ответ

0 голосов
/ 27 сентября 2011

При отладке одного из ваших вызовов службы, что WindowsIdentity.GetCurrent() возвращает вам?

Я полагаю, у вас есть проблема подражания; если это , а не учетная запись службы, то для операции / службы разрешено олицетворение (обратите внимание, что настройки на стороне клиента не требуют олицетворения, клиент и сервер должны совпадать), в этом случае вы должны указать разрешение на всех пользователей, которые вы выдаете за себя.

Или Вы можете просто указать, что хотите идентифицировать пользователя, но не точно подражать.

Если пользователь является вашей учетной записью службы, вам необходимо дважды проверить действующие разрешения для файлов, которые вы пытаетесь открыть для учетной записи, под которой работает ваша служба.

...