简体   繁体   English

没有客户端证书的WCF消息/方法安全性

[英]WCF message / method security without a client certificate

I have a WCF service, hosted in IIS. 我有一个托管在IIS中的WCF服务。 On the service, I have about 20 methods in the service. 在服务上,我在服务中有大约20种方法。 I would like to secure SOME of those methods with username/password. 我想用用户名/密码来保护这些方法。 I don't have any control over the clients that are calling the service, so I can't install a certificate on the client. 我无法控制调用该服务的客户端,因此无法在客户端上安装证书。 Our services act as a platform, holding all the user profile information, including login information. 我们的服务充当平台,包含所有用户配置文件信息,包括登录信息。

I THINK that I would like the clients to authenticate once to the Authenticate(username,password) method on the WCF service, get an authorization token back, and pass that token for subsequent calls. 我认为我希望客户端对WCF服务上的Authenticate(用户名,密码)方法进行一次身份验证,获取授权令牌,并将该令牌传递给后续调用。 (Sort of like Asp.net membership providers use of forms auth sessions). (类似于Asp.net成员资格提供者使用表单身份验证会话)。 I don't want the client to have to pass the username/password for every method call, if possible. 如果可能的话,我不希望客户端必须为每个方法调用传递用户名/密码。 Is this the right pattern? 这是正确的模式吗? Is there a better way to get this feature to work using standard WCF functionality? 是否有更好的方法可以使用标准WCF功能使此功能正常工作? Does anybody have any sample config/code to show the right way to get this to work? 有没有人有任何示例配置/代码来显示正确的方法来使其工作?

WCF does not provide per operation authentication out of the box. WCF不提供开箱即用的每个操作身份验证。 If you want secured and unsecured operations the easiest approach is to divide them into two service contracts and expose each with different security settings. 如果您想要安全和不安全的操作,最简单的方法是将它们分成两个服务合同,并使每个服务合同具有不同的安全设置。

Your idea of authorization token is already implemented in WCF but in your scenario you have to use wsHttpBinding, UserName client credentials, SecurityContext and service certificate. 您对授权令牌的想法已经在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 is interoperable feature based on WS-SecureConversation. SecurityContext是基于WS-SecureConversation的可互操作功能。 It requires passing user name and password only in first call from service proxy instance (in WCF this is fully transparent - client proxy instance maintains security context). 它只需要在服务代理实例的第一次调用中传递用户名和密码(在WCF中,这是完全透明的 - 客户端代理实例维护安全上下文)。 Following calls only use security token issued during first call. 以下呼叫仅使用首次呼叫期间发出的安全令牌。 SecurityContext is turned on by default in wsHttpBinding. 默认情况下,在wsHttpBinding中打开SecurityContext。

This configuration will also encrypt and sign messages - it is full power WS-Security. 此配置还将加密和签署消息 - 它是全功率WS-Security。 Any other approach is just up to you. 任何其他方法都取决于你。 You will have to implement it completely by yourselves. 你必须自己完全实现它。

You mentioned that you don't have control over clients. 您提到您无法控制客户端。 It doesn't mean that you can't use certificate. 这并不意味着您不能使用证书。 If you use certificate, it is responsibility of clients to get it if they want to call your service. 如果您使用证书,客户有责任在他们想要拨打您的服务时获取证书。 It has nothing to do with control over clients its about trust to the certificate - for public web service it means buying the certificate from trusted certification authority. 它与控制客户端无关,与证书的信任无关 - 对于公共Web服务,这意味着从受信任的证书颁发机构购买证书。

Moreover it is possible to get service certificate without installing it. 此外,无需安装即可获得服务证书。 First possibility is to use certificate as endpoint identity. 第一种可能性是使用证书作为端点身份。 In such case, encoded certificate is part of WSDL: 在这种情况下,编码证书是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>

This is automatically done if you specify wsHttpBinding endpoint with service certificate configured and you do not set its identity. 如果指定了配置了服务证书的wsHttpBinding端点并且未设置其标识,则会自动执行此操作。 Drawback of this method is that certificate expiration. 这种方法的缺点是证书过期。 If you change expired certificate all clients must be updated. 如果更改过期证书,则必须更新所有客户端。

Second possibility is to enable service credentials negotiation: 第二种可能性是启用服务凭证协商:

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

Negotiation is turned on by default. 默认情况下会启用协商。 It uses TLSNego protocol to exchange service credentials (certificate) before secure communication starts. 它使用TLSNego协议在安全通信开始之前交换服务凭证(证书)。 Drawback of this method is that TLSNego is not supported by all platforms. 这种方法的缺点是所有平台都不支持TLSNego。

FYI: If you want to use the built-in WCF custom user/pass subsystem, WCF 4.0 introduced an Allow Insecure Transport property . 仅供参考:如果要使用内置WCF自定义用户/传递子系统,WCF 4.0引入了“ 允许不安全传输”属性 This allows you to use the WCF security subsystem without certs etc... This is useful in situations where you consider the messaging to be secured even though WCF doesn't think it is (such as when SSL is done on an appliance level instead of a webserver level, or when IP filtering is used). 这允许您使用没有证书等的WCF安全子系统...这在您考虑保护消息传递的情况下很有用,即使WCF认为它不是(例如在设备级别上完成SSL而不是网络服务器级别,或使用IP过滤时)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM