Служба WCF с аутентификацией Windows не отвергает ненадежных пользователей - PullRequest
0 голосов
/ 08 июля 2019

Я разрабатываю режим «автоподключения» между приложением WPF и сервисом Windows WCF. Я хочу разрешить только доверенным пользователям домена подключаться к определенной службе WCF без необходимости использования учетных данных Windows (пользователь уже вошел в свой сеанс Windows). Эта служба затем зарегистрирует пользователя в приложении.

Я создал службу WCF с режимом безопасности для «Transport» и Transport.ClientCredentialType для «Windows» (одинаковая привязка как на клиенте, так и на сервере). В том же приложении выполняются другие службы WCF с режимом безопасности «Нет».

Когда я запускаю службу Windows на компьютере домена под учетной записью LocalService и запускаю клиент на другом компьютере под учетной записью пользователя домена, я могу получить идентификатор пользователя Windows «ДОМЕН \ пользователь» на стороне сервера в объекте OperationContext , Я вижу, что используется Kerberos, и я думаю, что есть какое-то подражание, которое в порядке.

Но когда я запускаю службу Windows на компьютере рабочей группы (вне домена), где пользователь домена не известен, для идентификатора OperationContext Windows устанавливается значение «MACHINE_NAME \ Administrator» (локальный сеанс, созданный на сервере). В сервисном звонке нет ошибок, нет исключений, и я не могу понять, почему. Свойство IsAuthenticated объекта WindowsIdentity всегда имеет значение true.

Я уже проверял в режиме безопасности «Сообщение».

Я хотел знать, есть ли возможность сказать WCF отклонить ВСЕ соединения, которые не являются подлинно аутентифицированными?

UPDATE : Вот некоторые сведения, которые могут помочь:

  • Клиентское приложение - это приложение WPF
  • Сервер - это классическая служба Windows, работающая в режиме LOCAL SERVICE
  • Привязки net.tcp
  • Классы прокси-клиентов создаются с помощью svcutil.exe
  • Все делается кодом, без конфигурационного файла
  • Вот код, создающий ServiceClient:
 public static TClient Create<TClient, TChannel>(params IContractBehavior[] behaviors)
          where TChannel : class
          where TClient : ClientBase<TChannel>
        {
            var typeOfClient = typeof(TClient);
            var ctor = typeOfClient.GetConstructor(new[] { _bindingType, _endpointAddressType });
            if (ctor == null)
            {
                throw new Exception($"{typeOfClient} has no constructor taking 2 parameters ({_bindingType},{_endpointAddressType})");
            }
            var address = getClientBaseEndPointAddress(typeof(TChannel));
            var binding = getBinding<TClient>(address.Uri.Scheme);
            var clt = (TClient)ctor.Invoke(new object[] { binding, address });
            foreach (var behavior in behaviors)
            {
                clt.ChannelFactory.Endpoint.Contract.Behaviors.Add(behavior);
            }
            manageDataContractResolver<TClient, TChannel>(clt);
            clt.setOperationTimeout(binding.SendTimeout);
            return clt;
        }
  • Метод getBinding используется приложением «Клиент и сервер»:
   var ret = new NetTcpBinding
   {
      MaxBufferSize = bc.MessageSize,
      MaxBufferPoolSize = bc.MessageSize,
      ...        
   };

   // Secured or not
   if (secured)
   {
      ret.Name = "Default_Secured_Binding";
      ret.Security.Mode = SecurityMode.Transport;
      ret.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows;      
    }
    else
    {
       ret.Security.Mode = SecurityMode.None;
       ret.Name = "Default_Binding";
    }

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

Дайте мне знать, если вам нужна дополнительная информация.

1 Ответ

0 голосов
/ 09 июля 2019

Если клиент не предоставляет учетные данные Windows в качестве учетных данных Windows-клиента, то учетные данные текущего пользователя компьютера будут использоваться для проверки подлинности. Условие для аутентификации состоит в том, что эти учетные данные могут быть зарегистрированы на сервере (пользователь Windows)
Как клиент вызывает сервис, клиентский прокси-класс или ChannelFactory? Вот подход к настройке учетных данных на стороне клиента.

ServiceReference2.Service1Client client = new ServiceReference2.Service1Client();
            //if we don't set up this, The computer user credentials that are currently running the program will be sent to the server.
            client.ClientCredentials.Windows.ClientCredential.UserName = "administrator";
            client.ClientCredentials.Windows.ClientCredential.Password = "123456";

при условии, что конфигурация на стороне сервера ниже,

  <system.serviceModel>
    <services>
      <service name="WcfService1.Service1">
        <endpoint address="" binding="wsHttpBinding" contract="WcfService1.IService1" bindingConfiguration="mybinding">
        </endpoint>
        <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"></endpoint>
      </service>
    </services>
    <bindings>
      <wsHttpBinding>
        <binding name="mybinding">
          <security mode="Transport">
            <transport clientCredentialType="Windows"></transport>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...