2
votes

How to secure a WCF service which can be consumed by Javascript clients? Any specific security model for this?

What I understand is WCF Support encryption of data over wire using Transport and Message Security. But the WCF is still not fuly secure because anyone can consume the service (Authentication is missing). Only the data moves "to and fro" is encrypted over the channel. Which is not sufficient. So, we introduced Mutual Authentication and choosed Certificate as cridentials.What the clients needs to do is: Along with all SOAP Request, he should send a valid certificate (client cridential contains public and PRIVATE KEY as well and issued by WCF Administrator) which is issued by a CA whom my servers trust.

We are using basicHttpBinding because our clients can be Javascript/Ipad/.Net/DBL clients. We are able to consume such services using .Net/SOAPUI/JAVA clients. So we were good with this approach.

But today during an Analysis we found that JavaScript clients can't consume our service because it doesnt support mutual authentication (correct me if I am wrong). Even if it support mutual authentication and post a valid Certificate to server, we cant afford all clients (web browsers) to provide the client certificate because it contains a Public and a PRIVATE keys as well (please note PRIVATE KEY AS WELL!!) and which my server trusts blindly.

Now I am little confused. Can someone suggest some security model which is supported by JavaScript without any security compromise. Something like RESTful WCF.

I understand that JavaScript doesnt support Message Security and it only supports Transport Security. I dont care how data gets encrypted over the wire. I care is how client gets authenticated by my WCF Service.

Many Thanks

2
You can try to use HMAC algorithm for authentication which is used by many service providers like amazon, etc...Rajesh

2 Answers

2
votes

If you are already using Form Authentication for your web site, then you can leverage the ASP.NET pipline to check for FormAuthentication Cookie by enabling AspNetCompatibilityRequirementsMode to Required. More details could be found in this SO thread

If your service is stand alone service and its just being consumed by different clients over which you do not have any control , then you could use oauth authentication in which there would be a consumer secret key which would be shared to all authenticated clients. The caller would sign some info using this key and server would also sign it using the same key and then compare it. For implementation details please look at this excellent article

0
votes

Oh I see... I am doing R&D on the component suggested by tou i.e. OAuth... What I am able to do so far is: exposed a webHttpBinding endpoint over SSL and my javascript client can invoke the SSL Secure service using $Ajax using JSONP... This means the channel is encrypted.. Now all I need is to apply the OAuth in the WCF... Could you guide me how a Javascript client will understand OAuth? I mean I have server code for OAuth downloaded from here (http://oauth.googlecode.com/svn/code/csharp/OAuthBase.cs) but how to invoke such service using javascript? I am parllely doing R&D on this point and will post if I get any ansower.

Here is my REST WCF over SSL Configuration hope it help someone:

<?xml version="1.0"?>

<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>

  <system.serviceModel>
    <bindings>
      <webHttpBinding>
        <binding name="jsonpSsl" crossDomainScriptAccessEnabled="true">
          <security mode="Transport" />
        </binding>
      </webHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="JsonServiceBehaviors">
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceMetadata httpsGetEnabled="true"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="webHttpBehavior">
          <webHttp />
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <services>
      <service name="WCFTransportSecurity.TransportSecurityService" behaviorConfiguration="JsonServiceBehaviors">
        <endpoint address="" binding="webHttpBinding" bindingConfiguration="jsonpSsl" contract="WCFTransportSecurity.ITransportSecurityService" behaviorConfiguration="webHttpBehavior"/>
      </service>
    </services>
  </system.serviceModel>

  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
</configuration>

And here is the JQuery AJAX call to the service (Hope it help someone)

 $.ajax(
            {
                type: "GET",
                data: "{}",
                contentType: "application/json; charset=utf-8",
                dataType: "jsonp",
                url: "https://localhost/WCFTransportSecurity/TransportSecurityService.svc/getdata/" + $("#TextBox1").val(),
                success: function (a) { $("#lblResponse").text(a); },
                error: function (a) {$("#lblResponse").html("Error while Processing: Error Code: " + a.status + "<br/>and Error Message: <span style='color:red'>" + a.statusText + "</span>"); }
            });