Динамическое связывание конечных точек WCF с HTTPS на основе привязок IIS - PullRequest
0 голосов
/ 07 марта 2020

У меня есть служба WCF, которую я конвертирую из HTTP в HTTPS. В настоящее время клиенты имеют жестко запрограммированный URL-адрес HTTP для этой службы. Сервер связывает службу, используя некоторые пользовательские поведения в файле Web.config:

  <service behaviorConfiguration="MyServiceBehaviors" name="MyService">
    <endpoint address="" behaviorConfiguration="MyEndpointBehaviors" binding="customBinding" bindingConfiguration="MyHttpCustomBinding" name="MyService" contract="IMyService" />
  </service>

Я хочу связать службу WCF с HTTP и HTTPS. Я могу сделать это с двумя записями в файле Web.config:

  <service behaviorConfiguration="MyServiceBehaviors" name="MyService">
    <endpoint address="" behaviorConfiguration="MyEndpointBehaviors" binding="customBinding" bindingConfiguration="MyHttpCustomBinding" name="MyService" contract="IMyService" />
    <endpoint address="" behaviorConfiguration="MyEndpointBehaviors" binding="customBinding" bindingConfiguration="MyHttpsCustomBinding" name="MyService" contract="IMyService" />
  </service>

У меня также есть требование, чтобы на сервере сначала не был включен HTTPS. Таким образом, IIS может не быть привязан к порту HTTPS 443 во время активации службы WCF.

Если IIS не привязан к HTTPS, а Web.config привязывается к обеим конечным точкам, как Приведенный выше пример, и клиент пытается активировать службу на конечной точке HTTP, не удается запустить службу со следующим исключением активации:

WebHost не удалось обработать запрос. Информация об отправителе: System.ServiceModel.ServiceHostingEnvironment + HostingManager / 45653674 Исключение: System.ServiceModel.ServiceActivationException: служба '/MyApp/MyService.svc' не может быть активирована из-за исключения во время компиляции. Сообщение об исключении: Не удалось найти базовый адрес, который соответствует схеме https для конечной точки с привязкой CustomBinding. Схемы зарегистрированных базовых адресов: [http].

Я думаю, что службе WCF необходимо привязываться к HTTPS только тогда, когда HTTPS включен в IIS. Я не вижу способа выполнить sh в файле Web.config, поэтому я предполагаю, что мне потребуется выполнить динамическое связывание c с сервером.

Как можно выборочно связать конечные точки HTTP и HTTPS в WCF на основе конфигурации IIS?

Я также не вижу способа, чтобы служба могла получать уведомления, если привязка IIS изменяется для добавления / удаления HTTPS, но я в порядке с попросить администраторов перезапустить пул приложений / IISRESET / reboot, чтобы служба использовала обновленные настройки.

1 Ответ

0 голосов
/ 07 марта 2020

Мне удалось заставить это работать со следующими шагами:

Добавить атрибут Factory в файл MyService.sv c, который сможет создать службу:

<%@ ServiceHost Language="C#" Debug="true"
    Service="MyService"
    Factory="MyServiceFactory" %>

Создание класса фабрики в DLL-библиотеке службы WCF:

public class MyServiceFactory : ServiceHostFactory
{
    public override ServiceHostBase CreateServiceHost(string service, Uri[] baseAddresses)
    {
        return CreateServiceHost(typeof(MyService), baseAddresses);
    }

    protected override ServiceHost CreateServiceHost(Type t, Uri[] baseAddresses)
    {
        var serviceHost = new ServiceHost(t, baseAddresses);
        foreach (Uri address in baseAddresses)
        {
            bool secure = false;
            if (address.Scheme == "https")
                secure = true;

            var binding = GetMyCustomBinding(secure);
            var endpoint = serviceHost.AddServiceEndpoint(typeof(IMyService), binding, address);

            endpoint.Behaviors.Add(new MyEndpointBehavior());
        }

        return serviceHost;
    }
}

В указанном массиве baseAddresses указана конечная точка Uris, к которой привязан IIS. Для каждой конечной точки свяжите службу с конечной точкой, используя пользовательскую привязку. Если конечной точкой является «https», используйте безопасную привязку; в противном случае используйте стандартную привязку.

...