Posts Tagged ‘REST’

Basic authentication of a .NET REST service

Tuesday, July 28th, 2009

One of the issues one can encounter when building a REST service with the .NET Framework 3.5 SP1 is the fact that when basic authentication is enabled, it defaults to authentication against Windows accounts in IIS. It’s not possible to specify your own handler/provider to authenticate against for instance a proprietary user database, nor is it possible to secure only a certain operation/service and leave the others unsecured.

Luckily there’s a open source project hosted on CodePlex called WCF REST Contrib which, besides adding a whole lot of other improvements, solves the aforementioned issues. The project provides a sample solution showcasing all the features, which might seem a bit overwhelming since it includes quite some configuration. I have attached a sample project with only the bare minimum configuration (using attributes) to enable per operation authentication.

Browse to CancerService.svc/request/skincancer to test the authentication, the browser should display a prompt asking for a username and password. The username is “tony” and password “clifton”. Don’t mind the rather questionable service and operation name, I had no inspiration at the time.

The original documentation failed to mention that the per operation/service authentication depended on the WebErrorHandler, which has been corrected.

Attachment: Authentication Tryout

Caching using WCF REST Starter Kit in Medium Trust

Sunday, April 26th, 2009

Caching is one of the features provided by the WCF REST Starter Kit released by Microsoft at CodePlex. Jesus Rodriguez has written a walkthrough on how to get it running. The kit was designed to run under Medium Trust, but if you want to use caching in this trust level, you’ll have to configure it a bit differently.

System.Security.SecurityException: Request for the permission of type ‘System.Configuration.ConfigurationPermission, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a’ failed.

Using Jesus’ approach you’ll be greated by a nice Security Exception, for some reason you can’t configure the caching in the Web.Config in Medium Trust. Luckily you can add all the caching configuration as attributes to your method. You’ll have to remove the <caching> block from the Web.Config, but leave the aspNetCompatibilityEnabled tag enabled! Here’s an example:

Instead of using this XML configuration:

<caching>
   <outputCacheSettings>
      <outputCacheProfiles>
         <clear/>
         <add name="SampleProfile" duration="30" enabled="true" location="Any" />
      </outputCacheProfiles>
   </outputCacheSettings>
</caching>

We add these attributes, unfortunately you’ll have to add these attributes to every method you’d like to cache. There are more attributes available, you can see them using the IntelliSense, but this configuration mimics the XML config.

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class SampleService : ISampleService
{
   [WebGet(UriTemplate= "/results")]
   [WebCache(Duration=30, Location=OutputCacheLocation.Any)]
   public Atom10FeedFormatter GetData()
   {
      ...
   }
}

Note: Tested in the ASP.NET Development Server provided by Visual Studio 2008 SP1. The OutputCacheLocation enum is located in the System.Web.UI namespace.

Removing svc extension of WCF REST service

Sunday, March 1st, 2009

What if we had a REST service implemented with WCF to retrieve some info about a user. The method would be called with the following url: “http://domain/service.svc/user/john”. Although this works perfectly and conforms to the REST guidelines, for some the svc extension is a thorn in the eye. Turns out it’s very easy to strip the svc extension with a HTTPModule. The module adds an eventhandler for the BeginRequest event of the application, each time a request is received the module checks if it is a call without the svc extension. If this is the case, it reroutes the request to service.svc with the specified parameters. To the outside world it will appear as if “http://domain/service/user/john” is called, while this resource actually does not exist.

public void Init(HttpApplication context)
{
   context.BeginRequest += delegate
   {
      HttpContext ctx = HttpContext.Current;
      string path = ctx.Request.AppRelativeCurrentExecutionFilePath.ToLower();
 
      if (path.Contains("/service/"))
      {
         int i = path.IndexOf('/', 2);
         if (i &gt; 0)
         {
            string service = path.Substring(0, i) + ".svc";
            string parameters = path.Substring(i, path.Length - i);
            ctx.RewritePath(service, parameters, string.Empty, false);
         }
      }
   };
}

In our case service would equals “~/service.svc” and the paramaters variable would equal “/user/john”.

Hooking the HTTPModule into the web.config is done in the system.web/httpmodules element. In this case the module class is called ServiceRedirector.

<system.web>
   <httpModules>  
      <add name="ServiceRedirector" type="ServiceRedirector"/>
   </httpModules>
</system.web>

The HTTPModule above could be extended to support multiple services, but I leave that as an exercise for the reader.