Требование SSL-сертификатов и клиентских сертификатов вызывает исключение в службе WCF JSON - PullRequest
4 голосов
/ 30 ноября 2011

У меня есть простая настройка службы WCF, которая использует JSON.В этом сервисе я хочу использовать клиентскую аутентификацию с клиентским сертификатом.Я настроил IIS 6 для запроса SSL и клиентских сертификатов, установив папку / site / services / wcf / json /.Эта настройка обычно называется двухсторонним SSL.

Но я получаю исключение, когда пытаюсь проверить страницу с созданным сертификатом SSL.

Настройки SSL дляслужба «Нет» не соответствует службам IIS «Ssl, SslNegotiateCert, SslRequireCert».

Stack Trace: 

[NotSupportedException: The SSL settings for the service 'None' does not match those of the IIS 'Ssl, SslNegotiateCert, SslRequireCert'.]
   System.ServiceModel.Activation.HostedAspNetEnvironment.ValidateHttpsSettings(String virtualPath, Nullable`1& requireClientCertificate) +117347
   System.ServiceModel.Channels.HttpsChannelListener.ApplyHostedContext(String virtualPath, Boolean isMetadataListener) +97
   System.ServiceModel.Activation.HostedAspNetEnvironment.ApplyHostedContext(TransportChannelListener listener, BindingContext context) +84
   System.ServiceModel.Channels.HttpsTransportBindingElement.BuildChannelListener(BindingContext context) +93
   System.ServiceModel.Channels.BindingContext.BuildInnerChannelListener() +63
   System.ServiceModel.Channels.MessageEncodingBindingElement.InternalBuildChannelListener(BindingContext context) +67
   System.ServiceModel.Channels.WebMessageEncodingBindingElement.BuildChannelListener(BindingContext context) +49
   System.ServiceModel.Channels.BindingContext.BuildInnerChannelListener() +63
   System.ServiceModel.Channels.Binding.BuildChannelListener(Uri listenUriBaseAddress, String listenUriRelativeAddress, ListenUriMode listenUriMode, BindingParameterCollection parameters) +125
   System.ServiceModel.Description.DispatcherBuilder.MaybeCreateListener(Boolean actuallyCreate, Type[] supportedChannels, Binding binding, BindingParameterCollection parameters, Uri listenUriBaseAddress, String listenUriRelativeAddress, ListenUriMode listenUriMode, ServiceThrottle throttle, IChannelListener& result, Boolean supportContextSession) +337
   System.ServiceModel.Description.DispatcherBuilder.BuildChannelListener(StuffPerListenUriInfo stuff, ServiceHostBase serviceHost, Uri listenUri, ListenUriMode listenUriMode, Boolean supportContextSession, IChannelListener& result) +668
   System.ServiceModel.Description.DispatcherBuilder.InitializeServiceHost(ServiceDescription description, ServiceHostBase serviceHost) +1228
   System.ServiceModel.ServiceHostBase.InitializeRuntime() +60
   System.ServiceModel.ServiceHostBase.OnBeginOpen() +27
   System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout) +50
   System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +318
   System.ServiceModel.Channels.CommunicationObject.Open() +36
   System.ServiceModel.HostingManager.ActivateService(String normalizedVirtualPath) +184
   System.ServiceModel.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath) +615

Я проверял, что сертификаты установлены правильно.Я создал базовый виртуальный каталог, который требует аутентификации клиента.Этот виртуальный каталог содержит простой файл .htm.Я подтвердил, что для него требуется https, и что это вызов мне для моего сертификата клиента, и когда я подтвердил действительный сертификат клиента, он отображает страницу .htm, а когда я не доказал действительный сертификат, это не так.

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

Вот мои настройки.

<system.serviceModel>
<!-- behaviors -->
<behaviors>
    <endpointBehaviors>
        <behavior name="jsonBehavior">
            <enableWebScript />
                <clientCredentials>
                <clientCertificate findValue="*.MyCompany.com" storeLocation="LocalMachine" x509FindType="FindBySubjectName" storeName="My" />
            </clientCredentials>
        </behavior>
    </endpointBehaviors>
    <serviceBehaviors>
        <behavior name="">
            <serviceDebug includeExceptionDetailInFaults="true" />
            <serviceMetadata httpsGetEnabled="true" httpGetEnabled="false" />
            <serviceCredentials>
                    <serviceCertificate  findValue="*.MyCompany.com" storeLocation="LocalMachine" x509FindType="FindBySubjectName" storeName="My" />                                              
                </serviceCredentials>
        </behavior>
    </serviceBehaviors>
</behaviors>

<!-- bindings -->
<bindings>
    <webHttpBinding>
        <binding name="webBinding">
            <security mode="Transport">
                <transport clientCredentialType="Certificate"/>
            </security> 
        </binding>
    </webHttpBinding>
</bindings>

<!-- services -->

<services>
    <service name="Service1Json" behaviorConfiguration="">
        <endpoint address="https://www.MyCompany.com/site/services/wcf/json/Service1.svc"
            behaviorConfiguration="jsonBehavior"
            binding="webHttpBinding"
            bindingConfiguration="webBinding"
            contract="MyCompany.Services.Wcf.IService1" />
    </service>
    <service name="Service2Json" behaviorConfiguration="">
        <endpoint address="https://www.MyCompany.com/site/Services/WCF/json/Service2.svc"
            behaviorConfiguration="jsonBehavior"
            binding="webHttpBinding"
            bindingConfiguration="webBinding"
            contract="MyCompany.Services.Wcf.IService2" />
    </service>
    <service name="Service3Json" behaviorConfiguration="">
        <endpoint address="https://www.MyCompany.com/site/services/wcf/json/Service3.svc"
            behaviorConfiguration="jsonBehavior"
            binding="webHttpBinding"
            bindingConfiguration="webBinding"
            contract="MyCompany.Services.Wcf.IService3" />
    </service>
</services>

<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />

</system.serviceModel>

1 Ответ

3 голосов
/ 12 декабря 2011

Проблема на самом деле оказалась более сложной, чем я описывал выше.И полученное решение оказалось довольно простым.

В первоначальной проблеме не упоминалось о том, что у нас несколько конечных точек: 1. SOAP 2. JSON.Они должны быть защищены с помощью двухстороннего SSL.

Наши ошибки были следующие:

  1. Учетные данные клиента и сервера не обязательны.
  2. Имя службы должно совпадать с именем файла .svc.
  3. Адреса конечных точек должны отличаться.Поэтому для нашей конечной точки JSON мы добавили «json».Также мы удалили полностью определенный URI из адреса и позволили WCF автоматически сгенерировать его для нас.

Вот окончательная конфигурация, с которой мы закончили:

<system.serviceModel>

    <!-- behaviors -->
    <behaviors>
        <endpointBehaviors>
            <behavior name="jsonBehavior">
                <enableWebScript />
            </behavior>
        </endpointBehaviors>
        <serviceBehaviors>
            <behavior name="">
                <serviceDebug includeExceptionDetailInFaults="true" />
                <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
            </behavior>
        </serviceBehaviors>
    </behaviors>

    <!-- bindings -->
    <bindings>
        <basicHttpBinding>
            <binding name="httpBinding">
                <security mode="None">
                </security>
            </binding>
        </basicHttpBinding>
        <webHttpBinding>
            <binding name="webBinding">
                <security mode="None">
                </security>
            </binding>
        </webHttpBinding>
    </bindings>

    <!-- services -->
    <services>
        <service name="MyCompany.Services.Wcf.Service1" behaviorConfiguration="">
            <endpoint address="json"
                behaviorConfiguration="jsonBehavior"
                binding="webHttpBinding"
                bindingConfiguration="webBinding"
                contract="MyCompany.Services.Wcf.IService1" />
            <endpoint address=""
                behaviorConfiguration=""
                binding="basicHttpBinding"
                bindingConfiguration="httpBinding"
                contract="MyCompany.Services.Wcf.IService1" />
        </service>

        <service name="MyCompany.Services.Wcf.Service2" behaviorConfiguration="">
            <endpoint address="json"
                behaviorConfiguration="jsonBehavior"
                binding="webHttpBinding"
                bindingConfiguration="webBinding"
                contract="MyCompany.Services.Wcf.IService2" />
            <endpoint address=""
                behaviorConfiguration=""
                binding="basicHttpBinding"
                bindingConfiguration="httpBinding"
                contract="MyCompany.Services.Wcf.IService2" />
        </service>

    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />

</system.serviceModel>

Если бы мы выбралиесли SOAP не использует двухсторонний SSL, а JSON требует двухстороннего SSL, конфигурация была бы намного более сложной.

...