Как настроить безопасность WCF для запроса сертификата клиента? - PullRequest
4 голосов
/ 05 декабря 2009

У меня есть сервис WCF. Я требую, чтобы клиенты проходили аутентификацию с помощью сертификата. Это конфигурация сервиса:

<system.serviceModel>
        <services>
            <service name="FilmLibrary.FilmManager" behaviorConfiguration="FilmService.Service1Behavior">
                <endpoint address="manager" name="certBinding" binding="basicHttpBinding" contract="FilmContract.IFilmManager" />
            </service>            
        </services>
        <bindings>
            <basicHttpBinding>
                <binding name="certBinding">
                    <security mode="Message">
                        <message clientCredentialType="Certificate" />
                    </security>
                </binding>
            </basicHttpBinding>
        </bindings>
        <behaviors>
            <serviceBehaviors>
                <behavior name="FilmService.Service1Behavior">
                    <serviceCredentials>
                        <clientCertificate>
                            <authentication trustedStoreLocation="LocalMachine" 
                            certificateValidationMode="PeerTrust" />
                        </clientCertificate>                                               
                    </serviceCredentials>    
            </behavior>
            </serviceBehaviors>
        </behaviors>
    </system.serviceModel>
</configuration>

Открытый ключ установлен в LocalMachine, Trusted People

Клиентская конфигурация выглядит следующим образом:

<system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="certBinding" closeTimeout="00:01:00" openTimeout="00:01:00"
                    receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
                    bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                    useDefaultWebProxy="true">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <security mode="Message">
                        <message clientCredentialType="Certificate"/>
                    </security>
                </binding>
            </basicHttpBinding>
        </bindings>
        <behaviors>
            <endpointBehaviors>
                <behavior name="certBehaviour">
                    <clientCredentials> 
                        <clientCertificate findValue="SubjectKey" storeLocation="CurrentUser" storeName="My" x509FindType="FindBySubjectName"/>
                    </clientCredentials>
                </behavior>
            </endpointBehaviors>
        </behaviors>
        <client>
            <endpoint address="[...]/Service1.svc/manager"
                binding="basicHttpBinding" bindingConfiguration="certBinding" behaviorConfiguration="certBehaviour"
                contract="FilmsService.IFilmManager" name="certBinding" />
        </client>
    </system.serviceModel>

Закрытый ключ установлен в Личный, текущий пользователь.

Без охраны, сервис работает. С включенной безопасностью - нет. Я попробовал несколько конфигураций, и я получил ошибки, такие как аутентификация не удалась или что мне нужно установить сертификат службы в элементе clientCredentials. Что я не понимаю, потому что я вообще не хочу аутентифицировать сервис.

Ответы [ 3 ]

3 голосов
/ 06 ноября 2015

Я нашел следующее руководство очень полезным и очень подробным. https://notgartner.wordpress.com/2007/09/06/using-certificate-based-authentication-and-protection-with-windows-communication-foundation-wcf/

Включает создание службы, клиента, сертификатов и настройку 2-х конфигов.

Сервер:

<bindings>
  <basicHttpBinding>
    <binding name="secureHttpBinding">
      <security mode="TransportWithMessageCredential">
        <message clientCredentialType="Certificate" />
      </security>
    </binding>
  </basicHttpBinding>
</bindings>

<behaviors>
  <serviceBehaviors>
    <behavior>
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />
      <serviceCredentials>
        <clientCertificate>
          <!--only accept certificates in "Trusted People"-->
          <authentication certificateValidationMode="PeerTrust" trustedStoreLocation="LocalMachine" />
        </clientCertificate>
      </serviceCredentials>
    </behavior>
  </serviceBehaviors>
</behaviors>

Клиент:

<bindings>
  <basicHttpBinding>
    <binding name="customBinding1">
      <security mode="TransportWithMessageCredential">
        <message clientCredentialType="Certificate" />
      </security>
    </binding>
  </basicHttpBinding>
</bindings>

<behaviors>
  <endpointBehaviors>
    <behavior name="customBehavior1">
      <clientCredentials>
        <!--fabrkam-->
        <clientCertificate storeName="My" storeLocation="CurrentUser" x509FindType="FindByThumbprint" findValue="d2 31 6a 73 1b 59 68 3e 74 41 09 27 8c 80 e2 61 45 03 b1 7e"/>
      </clientCredentials>
    </behavior>
  </endpointBehaviors>
</behaviors>

Мы автоматически перенаправляем любые HTTP-запросы в HTTPS, поэтому мы должны использовать тип защиты TransportWithMessageCredential. Для обычного Http использование только Message в качестве типа безопасности также должно работать.

2 голосов
/ 15 октября 2010

Мне удалось сделать то же самое с помощью настраиваемой привязки, например:

 <customBinding>
    <binding name="bindingName">
      <security authenticationMode="UserNameOverTransport" />
      <httpsTransport requireClientCertificate="true"/>
    </binding>
  </customBinding>

(я опустил атрибуты, не относящиеся к вашему делу.)

Что касается authenticationMode, я думаю, что вы, вероятно, можете использовать любой из них - httpsTransport с requireClientCertificate являются важными частями здесь.

2 голосов
/ 05 декабря 2009

вместо

            <serviceCredentials>
                <clientCertificate>
                    <authentication trustedStoreLocation="LocalMachine" 
                    certificateValidationMode="PeerTrust" />
                </clientCertificate>                                               
            </serviceCredentials>  

Я думаю, у вас должно быть

            <serviceCredentials>
                <serviceCertificate  findValue="SubjectKey" storeLocation="LocalMachine" storeName="TrustedPeople" x509FindType="FindBySubjectName"/>                                              
            </serviceCredentials>  

Вы не аутентифицируете сервис этим, вместо этого вы сообщаете сервису, как клиент должен аутентифицироваться.

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