Secure RESTful WCF Service with SHA-256 hashing

This is an old draft I found, perhaps it is useful if you’re trying to do SHA-256. If not, let me know, I might be able to help you out. Azure Storage supports secure access of resources without logon. It involves hashing the query part of the URL and then signing that hash. I’ve implemented this at my workplace in the following steps:

  • Create a web project for a WCF service.
  • Update the .svc file by adding (this makes everything work without configuration, found this here):

Factory="System.ServiceModel.Activation.WebServiceHostFactory"

  • Add the following attribute to your interface method:

[WebInvoke(Method = "GET", BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "?p0={parameter0}&p1={parameter1}&sig={signature}")]

  • Create a method like (please note that parameter names match those specified in the WebInvoke attribute and that they are all string type):

Stream MyMethod(string parameter0, string parameter1, string signature);

  • In the implementation of MyMethod verify the signature with the following function:

bool ValidSignature(string customerID, string signature, params string[] toSignArguments)
{
var certificate = FindCertificate(customerID);
if (certificate == null) {
return false;
}
const string TERMINATOR = "\n";
var toSign = string.Join(TERMINATOR, toSignArguments) + TERMINATOR;
var oldProvider = (RSACryptoServiceProvider)certificate.PublicKey.Key;
using (var newProvider = new RSACryptoServiceProvider())
{
newProvider.ImportCspBlob(oldProvider.ExportCspBlob(false));
return newProvider.VerifyData(Encoding.UTF8.GetBytes(toSign), "SHA256", Convert.FromBase64String(signature));
}
}

The trick is to create a new provider instead of the default one you get when loading the key. The default is connected to the wrong library that doesn’t support SHA-256.

URL Trailing Slash: subtle difference between Web API and WCF Rest

Just found an interesting difference between Web API and WCF Rest when you supply a URL with a trailing slash, e.g. http://server/path/1/.

Say you have a Web API deployed to server with a PathController. This will catch a URL with or without a trailing slash, so http://server/path/1 and http://server/path/1/ are equivalent.

On the other hand, assume you have a WCF Rest service deployed at server with a service contract containing a method decorated with [WebGet(UriTemplate=”path/{id}”)]. This will listen to http://server/service.svc/path/1 but http://server/service.svc/1/ will return an HTTP status code 404 with a message endpoint not found.

If the method is decorated with a trailing slash like [WebGet(UriTemplate=”path/{id}/”)] the service will listen to http://server/service.svc/path/1/. Trying to invoke it without the trailing slash like http://server/service.svc/path/1 will return an HTTP response code 307 Temporary Redirect with the equivalent location but including a trailing slash.

I now hope this won’t bite you as much as it bit me ;-).