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 не поддерживается всеми платформами.
Могу ли я сделать это с помощью 'netTCPBinding'? – Sreekumar