Служба WCF только через HTTPS - PullRequest
2 голосов
/ 06 февраля 2012

У меня есть служба RESTful WCF, которую я хочу разместить на сервере Windows Server 2008 R2.В настоящее время он размещается как приложение на существующем веб-сайте.Самозаверяющий сертификат используется для порта 443.

Я бы хотел, чтобы служба обслуживалась только по HTTPS.В настройках SSL для приложения я установил «Требовать SSL».Конечная конфигурация выглядит следующим образом:

  <system.serviceModel>
<behaviors>
  <endpointBehaviors>
    <behavior name="Rest">
      <webHttp />
    </behavior>
  </endpointBehaviors>
  <serviceBehaviors>

    <behavior>
      <serviceAuthorization serviceAuthorizationManagerType="ACME.MyAuthorizationManager, ACME.WS.Authorization" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<standardEndpoints>

  <webHttpEndpoint>

    <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true" />
  </webHttpEndpoint>
</standardEndpoints>

Однако я получаю 403 ответа при попытке доступа к службе через браузер (например, https://example.com/myservices/baz-service/yip-resource).

Я что-то пропустил во время настройки?

Ответы [ 2 ]

2 голосов
/ 07 февраля 2012

Установка параметра «Требовать SSL» в IIS означает, что вы выполняете аутентификацию с использованием клиентских сертификатов. Просто установите эту опцию, чтобы игнорировать или отключить эту опцию, если у вас нет аутентификации сертификата клиента.

Чтобы ваш сервис не обслуживался только по HTTPS, удалите HTTP-привязку из опции «Binding» на вашем веб-сайте. В противном случае просто предоставьте свои привязки для использования транспорта в качестве механизма безопасности, и это должно заботиться о том, чтобы ваша служба WCF обслуживалась только по HTTPS.

ОБНОВЛЕНИЕ:

Пожалуйста, узнайте, как у меня есть служба RESTful, размещенная на IIS с Https:

[ServiceContract]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class RestService
    {
        // TODO: Implement the collection resource that will contain the SampleItem instances

        private static List<SampleItem> sampleCollection = new List<SampleItem>();

        [WebGet(UriTemplate = "/get-Collection")]
        public List<SampleItem> GetCollection()
        {
            // TODO: Replace the current implementation to return a collection of SampleItem instances
            if (sampleCollection.Count == 0)
            {
                sampleCollection = new List<SampleItem>();
                sampleCollection.Add(new SampleItem() { Id = 1, StringValue = "Hello 1" });
                sampleCollection.Add(new SampleItem() { Id = 2, StringValue = "Hello 2" });
                sampleCollection.Add(new SampleItem() { Id = 3, StringValue = "Hello 3" });
                sampleCollection.Add(new SampleItem() { Id = 4, StringValue = "Hello 4" });
                sampleCollection.Add(new SampleItem() { Id = 5, StringValue = "Hello 5" });
            }
            return sampleCollection;
        }
}

My Global.asax:

public class Global : HttpApplication
    {
        void Application_Start(object sender, EventArgs e)
        {
            RegisterRoutes();
        }

        private void RegisterRoutes()
        {
            // Edit the base address of Service1 by replacing the "Service1" string below
            RouteTable.Routes.Add(new ServiceRoute("", new WebServiceHostFactory(), typeof(RestService)));
        }
    }

Мой файл web.config:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>


  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>

  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </modules>
  </system.webServer>

  <system.serviceModel>
    <diagnostics>
      <messageLogging logEntireMessage="true" logKnownPii="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" />
      <endToEndTracing propagateActivity="true" activityTracing="true" messageFlowTracing="true" />
    </diagnostics>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
    <standardEndpoints>
      <webHttpEndpoint>
        <!-- 
            Configure the WCF REST service base address via the global.asax.cs file and the default endpoint 
            via the attributes on the <standardEndpoint> element below
        -->
        <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true" maxBufferSize="500000" maxReceivedMessageSize="500000">          
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />          
        </standardEndpoint>
      </webHttpEndpoint>
    </standardEndpoints>
    <behaviors>
        <serviceBehaviors>
            <behavior name="">
                <serviceCredentials>
                    <serviceCertificate storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" findValue="localhost" />
                </serviceCredentials>
            </behavior>
        </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

Теперь в моем IIS указана привязка Https:

Site Bindings in IIS

Теперь мой виртуальный каталог был настроен с именем XmlRestService и, следовательно, когда я перехожу к ресурсу, я получаю следующий вывод:

Output from a REST Service on HTTPS

0 голосов
/ 15 апреля 2016

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

#if !DEBUG
    // check secure connection, raise error if not secure 
    IncomingWebRequestContext request = WebOperationContext.Current.IncomingRequest;
    if (!request.UriTemplateMatch.BaseUri.AbsoluteUri.StartsWith("https://"))
    {
        throw new WebProtocolException(HttpStatusCode.BadRequest, "Https is required to use this service.", null);
    }
#endif
...