Можно ли изменить WebServiceHost, чтобы избежать использования HttpListener?

StackOverflow https://stackoverflow.com/questions/2417554

  •  19-09-2019
  •  | 
  •  

Вопрос

Я ищу способ использовать WCF WebServiceHost без необходимости полагаться на класс HttpListener и связанные с ним проблемы с разрешениями (см. этот вопрос подробности).

Я работаю над приложением, которое локально взаимодействует с другим (сторонним) приложением через их REST API.

На данный момент мы используем WCF в качестве встроенного HTTP-сервера.Мы создаем WebServiceHost следующим образом:

String hostPath = "http://localhost:" + portNo;
WebServiceHost host = new WebServiceHost(typeof(IntegrationService), new Uri(hostPath));

// create a webhttpbinding for rest/pox and enable cookie support for session management
WebHttpBinding webHttpBinding = new WebHttpBinding();
webHttpBinding.AllowCookies = true;

ServiceEndpoint ep = host.AddServiceEndpoint(typeof(IIntegrationService), webHttpBinding, "");

host.Open()

ChannelFactory<IIntegrationService> cf = new ChannelFactory<IIntegrationService>(webHttpBinding, hostPath);
IIntegrationService channel = cf.CreateChannel();

Все работает хорошо, пока наше приложение запускается от имени администратора.Если мы запустим наше приложение на машине без административных привилегий, host.Open() выдаст исключение HttpListenerException с ErrorCode == 5 (ERROR_ACCESS_DENIED).

Мы можем обойти эту проблему, запустив httpcfg.exe из командной строки, но это настольное приложение, запускаемое одним щелчком мыши, и для нас это не такое долгосрочное решение.

Мы могли бы отказаться от WCF и написать собственный HTTP-сервер, но я бы хотел этого избежать, если это возможно.

Какой самый простой способ заменить HttpListener стандартным TCP-сокетом, сохраняя при этом все оставшиеся HTTP-структуры, предоставляемые WCF?

Это было полезно?

Решение

Вы можете легко составить свой собственный стек с помощью CustomBinding, используя протоколы более высокого уровня «как есть» и создав собственную версию HttpTransport, которая не поддерживается HttpListener или IIS.Выполнимо, конечно, но это большая работа.Разберите существующие биты HttpTransport с помощью Reflector — там МНОГО движущихся частей.Вероятно, вы могли бы взломать простой PoC через Socket за день или два, если вам не нужно ничего особенного, например HTTPS или фрагментирование, но сделать его надежным будет сложно. ЗдесьЭто хороший обзор множества ресурсов (возможно, уже немного устаревший).

Другие советы

Ваша проблема не связана с HttpListener.

Ваша проблема:* У вас есть приложение OneClick с ограниченными разрешениями, которое * пытается открыть порт сервера.

Это противоречие.Ненадежное приложение с ограниченными разрешениями НЕ ДОЛЖНО ОТКРЫВАТЬ СЕРВЕРНЫЙ ПОРТ.Вот почему это не допускается по определению.

Вы пробовали открыть обычный сокет-порт?Это тоже не должно сработать.

В общем, приложения конечных пользователей с ограниченным доверием не должны размещать веб-службу;)

Тем не менее, я был в похожей ситуации, пытаясь использовать WCF в сценарии взаимодействия с драйверами - слава богу, мое приложение запускается с полным разрешением.

Вы также можете посмотреть на разрыв достаточного количества Кассини чтобы сделать его доступным для размещения в вашем приложении и загрузить туда конвейер WCF (через файлы .svc и обработчик активации службы) - таким образом потребуется написать очень мало нового кода, но при этом вы получите довольно надежный и протестированный веб-сервер.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top