WCF/WSHttpBinding — Few Authentication scenarios.

Security/Authentication in WCF has many unique components to be taken care of, depending on the application’s requirements.Broadly speaking,
–> Securing the messages at endpoints.In message security,messages are encrypted/signed. WCF encrypt/decrypts the messages and transport layer just carries the messages from client to service.
–> Messages are kept safe during transit, either through http+X.503 certificates or https or dedicated secured TCP channels.The message should not be tampered and thus keeping integrity intact. Secure connection can be done by using certificates either on transport level (HTTPS) or on message level. Certificates used in reference to Https or SSL has nothing to do with WCF. Message level Certificate can be configured in WCF config file or in code.
–> Authenticating the service. The client should know that it’s the real intended service it’s talking to and sending data and vice-versa (authenticating the client).
Then lastly if everything goes fine, giving access to resources/operations, ie Authorization — which is completely excluded, in this post.

(1)There are many kinds of in-built binding available like,WSHttpBinding, netTCPBinding, BasicHttpBinding, etc etc..I will just focus on “WSHttpBinding” for now.

(2)Similarly there are many kinds of “Security Mode” (which totally depends on, what binding is being used).
a.Transport (Mutual authentication and message protection are provided at the transport level.By default the transport-level security is Windows security, or SSL over TCP.).
b.Message   (Mutual authentication and message protection are provided at the message level).
c.TransportWithMessageCredential (This uses the best of message & transport.The transport determines the transport-level security and hence setting the ClientCredentialType property of any transport security object is ignored. In other words, you can only set the ClientCredentialType of the message security object (for the WSHttpBinding binding).In this mode, you can use HTTPS/SSL at the transport layer, and message level authentication like UserName/Certificate.

(3)ClientCredentialType specifies what kind of Credentials, a client provides to server, to tell who it is and in turn authenticate. It depends on Security mode and binding.
Say if Binding is wsHttpBinding Then
–>if Security Mode is Transport –> ClientCredentialType can be Windows/certificate.
–>if Security Mode is Message –> ClientCredentialType can be Windows/certificate/UserName.
       
By default wsHttpBinding comes with MessageSecurity and windows authentication, assuming Service and Client are in the same domain. Below are few working and successfull configuration scenarios as obtained from MSDN. Ofcourse, you need to replace domain name, Certificate with your own values accordingly.Only the configuration settings/structure is good and can be mapped to various real live situations.

///////////////////////////////////////////////////////////////////////////////////////////////////////////////
Scenario 1:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

Binding = wsHttpBinding
Security mode = Message
ClientCredentialType = UserName
Protocol = http
Service Authentication = using X.509 certificate
Client Authentication = UserName and Password
Use of X.501 Certificate = Yes (needs to be installed only on service host and NOT on client)
At service end, the username/password supplied by client can be validated using CustomUsernamePasswordValidator.(Not shown here).
Suitable for any internet scenario, where secured username/password authentication is okay.

//service
<?xml version=”1.0″ encoding=”utf-8″?>
<configuration>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name=”ServiceCredentialsBehavior”>
          <serviceCredentials>
            <serviceCertificate findValue=”Contoso.com”
                                storeLocation=”LocalMachine”
                                storeName=”My”  
                                x509FindType=”FindBySubjectName” />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration=”ServiceCredentialsBehavior”
               name=”ServiceModel.Calculator”>
        <endpoint address=”
http://localhost/Calculator”
                  binding=”wsHttpBinding”
                  bindingConfiguration=”MessageAndUserName”
                  name=”SecuredByTransportEndpoint”
                  contract=”ServiceModel.ICalculator” />
      </service>
    </services>
    <bindings>
      <wsHttpBinding>
        <binding name=”MessageAndUserName”>
          <security mode=”Message”>           
            <message clientCredentialType=”UserName” />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <client />
  </system.serviceModel>
</configuration>

//client
<?xml version=”1.0″ encoding=”utf-8″?>
<configuration>
  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name=”WSHttpBinding_ICalculator” >
          <security mode=”Message”>
            <message clientCredentialType=”UserName” />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <client>
      <endpoint address=”
http://machineName/Calculator”
                binding=”wsHttpBinding”
                bindingConfiguration=”WSHttpBinding_ICalculator”
                contract=”ICalculator”
                name=”WSHttpBinding_ICalculator”>
        <identity>
//mandatory & has to same as Server’s Certificate name
//It specifies a Domain Name System (DNS) of the expected server identity
          <dns value =”Contoso.com” />             
        </identity>
      </endpoint>
    </client>
  </system.serviceModel>
</configuration>

 
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
Scenario 2:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

Binding = wsHttpBinding
Security mode = TransportWithMessageCredential
ClientCredentialType = UserName
Protocol = https
Service Authentication = https/Certificate
Client Authentication = UserName and Password

Notice that transport and metadata is secured by Https.Except that, it is exact same as the one above.

<bindings>
  <wsHttpBinding>
   <binding name=”wsHttpEndpointBinding”>
          <security mode=”TransportWithMessageCredential”>
            <message clientCredentialType=”UserName” />
          </security>
  </binding>
</wsHttpBinding>
</bindings>

<services>
  <service behaviorConfiguration=”ServiceBehavior” name=”Service”>
    <endpoint address=”
https://…” binding=”wsHttpBinding”
      bindingConfiguration=”wsHttpEndpointBinding”
      name=”wsHttpEndpoint” contract=”IService”>
    </endpoint>
    <endpoint address=”mex” binding=”mexHttpsBinding” bindingConfiguration=””
            name=”MexHttpsBindingEndpoint” contract=”IMetadataExchange” />

  </service>
</services>

<behaviors>
  <serviceBehaviors>
      <behavior name=”ServiceBehavior”>
          <serviceMetadata httpGetEnabled=”false” httpsGetEnabled=”true” />
          <serviceDebug includeExceptionDetailInFaults=”false” />
      </behavior>
  </serviceBehaviors>
</behaviors>

///////////////////////////////////////////////////////////////////////////////////////////////////////////////
Scenario 3:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

Binding = wsHttpBinding
Security mode = Message 
ClientCredentialType = Certificate
Protocol = http
Service Authentication = service certificate
Client Authentication = Client certificate
Use of X.501 Certificate = Yes (needed to be installed on service host as well as client machine.)

This setting means service will have certificate as well as each client machine. This needs to be done externally with Certificates obtained from any 3rd party. Client Certificate is used to authenticate each client.

<?xml version=”1.0″ encoding=”utf-8″?>
<configuration>
  <system.serviceModel>

    <bindings>
      <wsHttpBinding>
        <binding name=”WSHttpBinding_ICalculator”>
          <security mode=”Message”>
            <message clientCredentialType=”Certificate” />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>

    <behaviors>
      <serviceBehaviors>
        <behavior name=”ServiceCredentialsBehavior”>
          <serviceCredentials>
            <serviceCertificate findValue=”Contoso.com”
                                x509FindType=”FindBySubjectName” />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>

    <services>
      <service behaviorConfiguration=”ServiceCredentialsBehavior”
               name=”ServiceModel.Calculator”>
        <endpoint address=
http://localhost/Calculator
                  binding=”wsHttpBinding”
                  bindingConfiguration=”MessageAndCerficiateClient”
                  name=”SecuredByClientCertificate”
                  contract=”ServiceModel.ICalculator” />
      </service>
    </services>
   
    <client />
  </system.serviceModel>
</configuration>

//Client
<?xml version=”1.0″ encoding=”utf-8″?>
<configuration>
  <system.serviceModel>
    <behaviors>
      <endpointBehaviors>
        <behavior name=”endpointCredentialsBehavior”>
          <clientCredentials>
            <clientCertificate findValue=”Cohowinery.com”
               storeLocation=”LocalMachine”
              x509FindType=”FindBySubjectName” />
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <bindings>
      <wsHttpBinding>
        <binding name=”WSHttpBinding_ICalculator” >
          <security mode=”Message”>
            <message clientCredentialType=”Certificate” />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <client>
      <endpoint address=”
http://machineName/Calculator”
                behaviorConfiguration=”endpointCredentialsBehavior”
                binding=”wsHttpBinding”
                bindingConfiguration=”WSHttpBinding_ICalculator”
                contract=”ICalculator”
                name=”WSHttpBinding_ICalculator”>
        <identity>
          <dns value=”Contoso.com” />
        </identity>
      </endpoint>
    </client>
  </system.serviceModel>
</configuration>

///////////////////////////////////////////////////////////////////////////////////////////////////////////////
Scenario 4:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

Binding = wsHttpBinding
Security mode = Transport
ClientCredentialType = Certificate
Protocol = https
Service Authentication = https
Client Authentication = Client certificate

//Same as the earlier one, but Security mode is Transport which means service is authenticated using SSL Certificate.
//Client produces the X.501 certificate to identify itself.

<configuration>
  <system.serviceModel>
    <protocolMapping>
      <add scheme=”https” binding=”wsHttpBinding” />
    </protocolMapping>
    <bindings>
      <wsHttpBinding>
        <!– configure wsHttp binding with Transport security mode and clientCredentialType as Certificate –>
        <binding>
          <security mode=”Transport”>
            <transport clientCredentialType=”Certificate”/>           
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <!–For debugging purposes set the includeExceptionDetailInFaults attribute to true–>
    <behaviors>
      <serviceBehaviors>
        <behavior>         
           <serviceDebug includeExceptionDetailInFaults=”True” />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

/Client
<configuration>
  <system.serviceModel>
    <client>
      <!– this endpoint has an https: address –>
      <endpoint address=”
https://localhost/CalculatorService/service.svc
                behaviorConfiguration=”endpointCredentialBehavior”
                binding=”wsHttpBinding”
                bindingConfiguration=”Binding1″
                contract=”Microsoft.Samples.TransportSecurity.ICalculator”/>
    </client>
    <behaviors>
      <endpointBehaviors>
        <behavior name=”endpointCredentialBehavior”>
          <clientCredentials>
            <clientCertificate findValue=”contoso.com”
                               storeLocation=”CurrentUser”
                               storeName=”My”
                               x509FindType=”FindBySubjectName” />
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <bindings>
      <wsHttpBinding>
        <!– configure wsHttpbinding with Transport security mode
                   and clientCredentialType as Certificate –>
        <binding name=”Binding1″>
          <security mode=”Transport”>
            <transport clientCredentialType=”Certificate”/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
  </system.serviceModel>

Reference: http://wcfsecurity.codeplex.com/
That’s it. Thanks for reading.

Advertisements
This entry was posted in WCF. Bookmark the permalink.

2 Responses to WCF/WSHttpBinding — Few Authentication scenarios.

  1. smitha says:

    Ok Confusing for starters like me.. But just tell me what kinda of security mode should I use. My outgoing consumer request will have 2 X509 tokens and one username token

  2. En says:

    Great post. The scenario driven approach is really practical.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s