4

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

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

ответ

4

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> 

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

+1

Могу ли я сделать это с помощью 'netTCPBinding'? – Sreekumar

1

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

Смежные вопросы