Безопасность сообщений / методов WCF без сертификата клиента - PullRequest
4 голосов
/ 26 января 2011

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

Я думаю, что я хотел бы, чтобы клиенты один раз проходили аутентификацию в методе Authenticate (имя пользователя, пароль) в службе WCF, получали токен авторизации и передавали этот токен для последующих вызовов. (Вроде как провайдеры членства в Asp.net используют формы авторизационных сессий). Я не хочу, чтобы клиент передавал имя пользователя / пароль для каждого вызова метода, если это возможно. Это правильный шаблон? Есть ли лучший способ заставить эту функцию работать, используя стандартные функции WCF? У кого-нибудь есть пример конфигурации / кода, чтобы показать правильный способ заставить это работать?

Ответы [ 2 ]

4 голосов
/ 26 января 2011

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

Ваша идея токена авторизации уже реализована в WCF, но в вашем сценарии вы должны использовать wsHttpBinding, учетные данные клиента UserName, SecurityContext и сертификат службы.

  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="securedService">
          <serviceCredentials>
            <serviceCertificate x509FindType="FindBySubjectName" findValue="ServerCert" 
                                storeLocation="LocalMachine" storeName="My"/>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <wsHttpBinding>
        <binding name="Secured">
          <security mode="Message">
            <message clientCredentialType="UserName" establishSecurityContext="true" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <services>
      <service name="MessageSecurity.Service" behaviorConfiguration="securedService">
        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="Secured"
                  contract="MessageSecurity.IService">
        </endpoint>
      </service>
    </services>
  </system.serviceModel>

SecurityContext - это функционально совместимая функция, основанная на WS-SecureConversation. Это требует передачи имени пользователя и пароля только при первом вызове из экземпляра прокси-сервера (в WCF это полностью прозрачно - экземпляр прокси-клиента поддерживает контекст безопасности). При последующих вызовах используется только токен безопасности, выданный во время первого вызова. SecurityContext включен по умолчанию в wsHttpBinding.

Эта конфигурация также будет шифровать и подписывать сообщения - это полная мощность WS-Security. Любой другой подход зависит только от вас. Вам придется полностью реализовать это самостоятельно.

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

Кроме того, можно получить сервисный сертификат, не устанавливая его. Первая возможность - использовать сертификат в качестве идентификатора конечной точки. В таком случае закодированный сертификат является частью WSDL:

<wsdl:service name="Service">
  <wsdl:port name="WSHttpBinding_IService" binding="tns:WSHttpBinding_IService">
    <soap12:address location="http://localhost:1432/Service.svc" /> 
    <wsa10:EndpointReference>
      <wsa10:Address>http://localhost:1432/Service.svc</wsa10:Address> 
      <Identity xmlns="http://schemas.xmlsoap.org/ws/2006/02/addressingidentity">
        <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
          <X509Data>
            <X509Certificate>MIICmzCCAYegAwI....<X509Certificate> 
          </X509Data>
        </KeyInfo>
      </Identity>
    </wsa10:EndpointReference>
  </wsdl:port>
</wsdl:service>

Это выполняется автоматически, если вы указываете конечную точку wsHttpBinding с настроенным сертификатом службы и не устанавливаете ее идентификатор. Недостатком этого метода является истечение срока действия сертификата. При изменении сертификата с истекшим сроком действия все клиенты должны быть обновлены.

Вторая возможность - включить согласование учетных данных службы:

<bindings>
  <wsHttpBinding>
    <binding name="Secured">
      <security mode="Message">
        <message clientCredentialType="UserName" negotiateServiceCredential="true"/>
      </security>
    </binding>
  </wsHttpBinding>
</bindings>

Переговоры включены по умолчанию. Он использует протокол TLSNego для обмена служебными учетными данными (сертификатом) до начала безопасной связи. Недостатком этого метода является то, что TLSNego поддерживается не всеми платформами.

1 голос
/ 26 января 2011

К вашему сведению: если вы хотите использовать встроенную пользовательскую подсистему пользовательских / проходных WCF, в WCF 4.0 добавлено свойство Allow Insecure Transport . Это позволяет использовать подсистему безопасности WCF без сертификатов и т. Д. Это полезно в ситуациях, когда вы считаете, что обмен сообщениями защищен, даже если WCF не считает, что это так (например, когда SSL выполняется на уровне устройства вместо уровень веб-сервера или при использовании IP-фильтрации).

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