Proxy Considerations

patterns & practices Developer Center

  • How to: Avoid Proxy Spoofing
  • How to: Publish Service Metadata for Your Clients
  • How to: Create a Proxy for an IIS-hosted Service with Certificate Authentication and Transport Security

How to: Avoid Proxy Spoofing

Consider the following to avoid proxy spoofing at the time of adding a WCF service reference:

  • Publish metadata securely, over Secure HTTP (HTTPS). Use mexHttpsBinding and configure a server certificate for the service. The following configuration shows how to publish metadata securely:

    <serviceMetadata httpGetEnabled="False" httpsGetEnabled="True"/>
    
  • If you are required to use a mex endpoint instead of exposing your service reference by using httpGet, use a secure binding. Use any standard binding (that has security features) for the mex service endpoint; the only requirement is to use the IMetadataExchange contract. This will require you to use a custom serviceutil.exe.config file to generate the proxy.

Consider the following to avoid proxy spoofing at run time:

  • Make sure that your WCF service uses mutual authentication. Mutual authentication is enforced when using either message or transport security.
  • If you are using basicHttpBinding, this binding does not use any security by default. Make sure that it is configured to use either transport or message security.
  • Do not rely on the NTLM protocol for authentication because it does not provide mutual authentication.

How to: Publish Service Metadata for Your Clients

To publish service metadata for your clients:

  1. If your service uses HTTP binding, you will need to enable metadata via httpGet or httpsGet. httpGet is required if you are not using transport security. httpsGet is required if you are using transport security. The trade-off with this configuration is that clients will be able to browse your service metadata.

    <serviceMetadata httpsGetEnabled="true" />
    <serviceMetadata httpGetEnabled="true"  />
    
  2. If your service uses HTTP binding, you can use a mex endpoint without enabling httpGet or httpsGet. In this case, browsers will not be able to browse metadata, but the clients will be able to create proxies using the mex endpoint. The trade-off with this configuration is that mex endpoints are not possible if IIS does not have anonymous authentication enabled.

    <system.serviceModel>
        <services>
          <service behaviorConfiguration="" name="Service">
            <endpoint address="" binding="wsHttpBinding" bindingConfiguration=""
              name="WsBinding" contract="IService" />
    <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration=""
              name="mexendpoint" contract="IMetadataExchange" />
          </service>
        </services>
       … 
      </system.serviceModel>
    
  3. If your service uses HTTP binding, you can use a custom endpoint that implements IMetadataExchange without enabling httpGet or httpsGet. In this case, browsers will not be able to browse metadata, but the clients will be able to create proxies using the mex endpoint. Additionally, you will be able to use the mex endpoint with any authentication scheme.

    <services>
        <service behaviorConfiguration="returnFaults" name="MyService">
          <endpoint binding="wsHttpBinding" bindingConfiguration=""
            name="wsHttpEndpoint" contract="IService" />
          <endpoint address="mex" binding="wsHttpMexBinding" 
            bindingConfiguration=""
            name="mexEndpoint" contract="IMetadataExchange" />
        </service>
      </services>
    …
    
  4. If your service does not use HTTP binding, you will need to configure service metadata and create a mex endpoint as follows:

    <system.serviceModel>
        <behaviors>
          <serviceBehaviors>
            <behavior name="BehaviorConfiguration">
              <serviceDebug includeExceptionDetailInFaults="true" />
              <serviceMetadata />
            </behavior>
          </serviceBehaviors>
        </behaviors>
        …
        <services>
          <service behaviorConfiguration="BehaviorConfiguration" 
                   name="WCFServicecHost.MyService">
    <endpoint 
               address="Mex" 
               binding="mexTcpBinding" 
               bindingConfiguration=""
               name="MexEndpoint" 
               contract="IMetadataExchange" />
            <endpoint 
               address="" 
               binding="netTcpBinding"
               bindingConfiguration="BindingConfiguration"
               name="TcpBinding" 
               contract="WCFServicecHost.IMyService" /> 
          </service>
        </services>
     </system.serviceModel>
    

Additional Resources

How to: Create a Proxy for an IIS-hosted Service with Certificate Authentication and Transport Security

Perform the following steps to create a proxy to a service hosted in IIS that requires certificate authentication and transport security:

  1. Create a new wsHttpBinding endpoint on the service that implements IMexdataExchange and uses a binding configuration with the certificate authentication type.

    <services>
       <service behaviorConfiguration="returnFaults" name="MyService">
          <endpoint binding="wsHttpBinding" bindingConfiguration=""
            name="wsHttpEndpoint" contract="IService" />
          <endpoint address="mex" binding="wsMexHttpBinding" 
            bindingConfiguration=""
            name="mexEndpoint" contract="IMetadataExchange" />
        </service>
    </services>
    …
    
  2. Create a svcutil.exe.config file on the client with configuration pointing to the certificate used to authenticate the service. The endpoint should have the contract with the IMetadataExchange type and will point to a binding configuration with certificate authentication.

    <configuration>
      <system.serviceModel>
        <client>
          <endpoint behaviorConfiguration="ClientCertificateBehavior" 
    binding="wsHttpBinding"
            bindingConfiguration="Binding1" contract="IMetadataExchange" 
      name="https" />
        </client>
        <bindings>
          <wsHttpBinding>
            <binding name="Binding1">
              <security mode="Transport">
                <transport clientCredentialType="Certificate" />
              </security>
            </binding>
          </wsHttpBinding>
        </bindings>
        <behaviors>
          <endpointBehaviors>
            <behavior name="ClientCertificateBehavior">
              <clientCredentials>
                <clientCertificate findValue="CN=clienttempcert" 
    storeLocation="CurrentUser"
                  storeName="My" 
    x509FindType="FindBySubjectDistinguishedName" />
              </clientCredentials>
            </behavior>
          </endpointBehaviors>
        </behaviors>
      </system.serviceModel>
    </configuration>
    
  3. Copy svcutil from C:\Program Files\Microsoft Visual Studio 8\Common7\IDE to the same location where svcutil.exe.config was created on the client, and then run the command svcutil serviceurl.

Additional Resources