Tag Archives: WCF Web API

WCF Web API–HTTP Message classes

This is the fifth post on a series about the new Preview 4 of WCF Web API. The previous posts were:

In this post, I briefly present the HTTP message classes, which are at the core of the WCF Web API processing model.

The following diagram shows the main classes for representing both requests and responses.HttpMessages

  • The two main classes are HttpRequestMessage, representing a HTTP request; and HttpResponseMessage, representing a HTTP response.
  • Both HttpRequestMessage and HttpResponseMessage have a Content property, of type HttpContent (abstract class) that represents the message’s body. Some available concrete content classes are
    • ByteArrayContent;
    • StringContent;
    • FormUrlEncodedContent;
    • StreamContent.
  • There are three different classes for message header representation
  • These classes are composed by a set of properties, one for each represented header. This allow for an easier access to headers (e.g. someRequest.Headers.Accept).
  • Note that the entity-headers are referenced by the content class and not directly by the request or response classes.
  • Note also that both the request’s Method and the response’s StatusCode are classes/enums and not just strings or integers.
  • Both HttpRequestMessage and HttpResponseMessage are concrete classes with public constructors, allowing for their simple instantiation, namely in testing scenarios.
  • Despite their core role in the HTTP Web API, these message classes belong to a different assembly – Microsoft.Net.Http.

WCF Web API–IIS Hosting

This is the fourth post on a series about the new WCF Web API – Preview 4.

In the second post, I described how to create self hosted services. In this post, I’ll show how to host on IIS.

1. Create a empty ASP.NET web application and map a IIS site or virtual directory into it. On my development environment, I usually create a new site for each project and use the hosts file to map the site name to 127.0.0.1.

2. Ensure the following on the web.config

  <!-- Ensure the UrlRoutingModule -->
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <add name="UrlRoutingModule"
               type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </modules>
  </system.webServer>

  <!-- Enable ASP.NET compatibility -->
  <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
  </system.serviceModel>

The UrlRoutingModule is used to route the requests into the WCF runtime.

3. Add the following route map to the application start (global.asax)

public class Global : System.Web.HttpApplication
{
    protected void Application_Start(object sender, EventArgs e)
    {
        ...
        RouteTable.Routes.MapServiceRoute&lt;TodoResource&gt;("todos");
        ...
    }
}

where TodoResource is the resource class (service class) and “todos” is the base path.

The MapServiceRoute extension methods adds a ServiceRoute to the RouteTable.Routes collection. This ServiceRoute uses a host factory that will produce a HttpConfigurableServiceHost. This host derives from the new HttpServiceHost, introduced on a previous post.

The MapServiceRoute also accepts an IHttpHostConfigurationBuilder, which can be used to configure the service. This configuration model, also applicable to self-hosting scenarios, will be the subject of a future post.

WCF Web API – Self-hosting, HTTPS and HTTP Basic Authentication

(Edited on 02/26/2012: WCF Web API is now ASP.NET Web API, which introduced some breaking changes. However, I’ve a new post describing how to enable HTTPS with self-hosting, on the ASP.NET Web API Beta)

(Edited on 09/24/2011: There is a new version of the code below, for the Preview 5 release. The major changes are on the configuration model.)

This is the third post on a series about the new WCF Web API – Preview 4.

In the last post, I described how to create self hosted services. In this post, I show how to use HTTPS and Basic Authentication for these services.

Self-hosting and HTTPS

Both self-hosting and IIS-hosting use the HTTP.sys windows component for HTTP request listening. This HTTP.sys component handles the transport level issues, such as the SSL protocol.

One of the configurations that must be done at the HTTP.sys level is the definition of the server certificate and private key, since the SSL protocol handshake is performed by this component.

When using IIS, the HTTP.sys configuration is done via the IIS manager. However, when self-hosting, the netsh command line utility must be used.

So, the first step is to register the server side certificate using the following command

netsh http add sslcert ipport=0.0.0.0:port certhash=thumbprint appid={app-guid}

where

  • port is the listening port (e.g. 443); the special IP address 0.0.0.0 matches any IP address for the local machine;
  • thumbprint is the certificate’s SHA-1 hash, represented in hexadecimal;
  • app-guid is any GUID, used to identity the owning application.

This command allows for other optional parameters, such as clientcertnegotiation, that define complementary SSL aspects.

For more information about this subject, I recommend:

Endpoints and HTTPS

In order for a WCF endpoint to use HTTPS, instead of plain HTTP, the endpoint’s binding must be properly defined. The new HttpBinding has a constructor overload that receives an HttpBindingSecurityMode. The options are:

  • None – no security;
  • Transport –both authentication and transport level protection, i. e., HTTPS;
  • TransportCredentialOnly – only authentication.

Endpoints and HTTP Basic Authentication

The authentication mechanism (e.g. HTTP Basic Authentication or client certificates) is also defined at the binding, via the Security.Transport.ClientCredentialType property.

The credential validation policy, username and password in the case of HTTP Basic Authentication, is defined at the service host, using the Credentials.UserNameAuthentication property.

The following code excerpt shows both the binding and host configuration.

using (var host = new HttpServiceHost(typeof(TheResourceClass), new string[0]))
{
    var binding = new HttpBinding(HttpBindingSecurityMode.Transport);
    binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
    var ep = host.AddServiceEndpoint(typeof(TheResourceClass),
                                                             binding,
                                                             "https://localhost:8435/greet");
    ep.Behaviors.Add(new HttpBehavior()
        {
            OperationHandlerFactory = new MyOperationHandlerFactory()
        });
    host.Credentials.UserNameAuthentication.UserNamePasswordValidationMode =
    UserNamePasswordValidationMode.Custom;
    host.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new MyCustomValidator();
    host.Open();
    Console.WriteLine("Service is opened, press any key to continue");
    Console.ReadKey();
}

The custom validator derives from UserNamePasswordValidator

class MyCustomValidator : UserNamePasswordValidator
{
    public override void Validate(string userName, string password)
    {
        if(!credentials are valid)
            throw new FaultException("Unknown Username or Incorrect Password");
    }
}

Accessing the user’s identity

The final issue regards the access to the user’s identity, obtained from the authentication process.  It would be nice if the request handling operation could receive this information as a parameter.

[ServiceContract]
class TheResourceClass
{
    [WebGet(UriTemplate = "")]
    HttpResponseMessage GetGreetings(IPrincipal principal)
    {
        return new HttpResponseMessage()
        {
            StatusCode = HttpStatusCode.OK,
            Content = new StringContent("hello "+principal.Identity.Name)
        };
    }
}

In above example, the GetGreetings operation receives an IPrincipal with the user’s identity. This parameter is injected into the operation by an operation handler, which is a new WCF Web API concept.  This new concept alone deserves one or more future posts, so here I will only present the required code.

class PrincipalFromBasicAuthenticationOperationHandler : HttpOperationHandler<HttpRequestMessage,IPrincipal>
{
    public PrincipalFromBasicAuthenticationOperationHandler() : base("Principal") { }

    public override IPrincipal OnHandle(HttpRequestMessage input)
    {
        if (input.Headers.Authorization == null || input.Headers.Authorization.Scheme != "Basic")
        {
            // If properly configured, this should never happen:
            // this OperationHandler should only be used when
            // Basic authorization is required
            throw new HttpResponseException(HttpStatusCode.InternalServerError);
        }
        var encoded = input.Headers.Authorization.Parameter;
        var encoding = Encoding.GetEncoding("iso-8859-1");
        var userPass = encoding.GetString(Convert.FromBase64String(encoded));
        int sep = userPass.IndexOf(':');
        var username = userPass.Substring(0, sep);
        var identity = new GenericIdentity(username, "Basic");
        return new GenericPrincipal(identity, new string[] { });
    }
}

The above operation handler extracts the user name from the “Authorization” header, whose credentials were previously validated via the custom validator, and creates a GenericPrincipal with that name.

Next, an operation handler factory is required to register this new operation handler.

class MyOperationHandlerFactory : HttpOperationHandlerFactory
{
    protected override Collection<HttpOperationHandler> OnCreateRequestHandlers(ServiceEndpoint endpoint, HttpOperationDescription operation)
    {
        var coll = base.OnCreateRequestHandlers(endpoint, operation);
        if (operation.InputParameters.Any(p => p.Type.Equals(typeof(IPrincipal))))
        {
            var binding = endpoint.Binding as HttpBinding;
            if (binding != null && binding.Security.Transport.ClientCredentialType == HttpClientCredentialType.Basic)
            {
                coll.Add(new PrincipalFromBasicAuthenticationOperationHandler());
            }
        }
        return coll;
    }
}

Notice that the PrincipalFromBasicAuthenticationOperationHandler is only inserted if the operation requires an IPrincipal and the endpoint is using HTTP Basic Authentication.

Finally, the factory is configured into the HttpBehavior used when defining the endpoint.

var ep = host.AddServiceEndpoint(typeof(TheResourceClass), binding, "https://localhost:8435/greet");
ep.Behaviors.Add(new HttpBehavior()
    {
        OperationHandlerFactory = new MyOperationHandlerFactory()
    });

Concluding remarks

  • Security is one of the WCF Web API where more changes are expected in the future. For example, the current sample uses the built in support for HTTP Basic Authentication provided by the “old” WCF HTTP transport channel. In the future, this functionality may be provided by other means (e. g. via a HttpMessageChannel/HttpMessageHandler).
  • Configuration is another area expected to change in the future. In this sample, I configure the endpoint directly, via the HttpBehavior. In the future, this may not be the preferred or adequate way to do this.
  • Unfortunately, the way Basic Authentication is currently implemented by the transport channel has the following issue: after the first invalid (username, password) pair, the response will be 403 and not 401. This means that the password would not be requested again by a typical user-agent. See  http://blogs.msdn.com/b/drnick/archive/2010/02/02/fix-to-allow-customizing-the-status-code-when-validation-fails.aspx for more details.

WCF Web API–Self-hosting

This is the second post on a series about the new Preview 4 of WCF Web API. In the previous post, I introduced the elementary aspects of the programming model, namely: resource classes, operations, HttpRequestMessage and HttpResponseMessage. The main outcome of the post was the TodoResource class.

In this post, I describe how to self-host this class. Lets the code do the talking.

class TheHostProgram
{
    static void Main(string[] args)
    {
        var instance = new TodoResource(new ToDoMemoryRepository());
        using (var host = new HttpServiceHost(instance, "http://localhost:8080/todo"))
        {
            host.Open();
            ShowEndpointsOf(host);
            WaitForKey();
        }
    }

    private static void ShowEndpointsOf(ServiceHost host)
    {
        Console.WriteLine("Host is opened with the following endpoints:");
        foreach (var ep in host.Description.Endpoints)
        {
            Console.WriteLine("\tEndpoint: address = {0}; binding = {1}", ep.Address, ep.Binding);
        }
    }

    private static void WaitForKey()
    {
        Console.WriteLine("Press any key to stop host...");
        Console.ReadKey();
    }
}

That’s it.

Notice:

  • The ShowEndpoints and WaitForKey methods are just utility functions to show the opened endpoints and wait for user input.
  • The use of a new service host type – HttpServiceHost.
  • For simplicity, the service uses InstanceContextMode.Single. This means that I can pass the resource class instance directly to the service host. This allows me to resolve its dependencies (the IToDoRepository) manually. In a future post, I will show how to use an IoC/DI container to obtain the resource class instances.
  • No endpoint has to be explicitly added. The HttpServiceHost automatically adds an endpoint for each defined base address defined in the constructor.
  • This default endpoint will have the “http://localhost:8080/todo” base address. Note that the URI templates defined in the resource class are relative to this base address. For instance, a GET request to “http://localhost:8080/todo/123” will be associated with the GetToDo operation (“{id}” template). The template’s id variable will be bound to “123”.

Explicit endpoints can also be added using the old AddServiceEndpoint method, before the service is opened:

host.AddServiceEndpoint(typeof(TodoResource), new HttpBinding(), "http://localhost:8080/todo2");

The host will not add default endpoints if there are explicit endpoints added.

When explicitly adding an endpoint, notice  the usage of a new binding – HttpBinding. This is the binding also used in the default endpoints.

Currently, it is even possible to use the old ServiceHost to host a resource class. However, the new HttpBehavior behavior must be added to each endpoint.

var repository = new ToDoMemoryRepository();
repository.Add(new ToDo("Must learn HTTP better"));
var instance = new TodoResource(repository);
using (var host = new ServiceHost(instance))
{
    var ep = host.AddServiceEndpoint(typeof(TodoResource), new HttpBinding(), "http://localhost:8080/todo2");
    ep.Behaviors.Add(new HttpBehavior());
    host.Open();
    ShowEndpointsOf(host);
    WaitForKey();
}

It is this HttpBehavior and the HttpBinding that “insert” the new WCF Web API model into the WCF runtime. When using HttpServiceHost, this behavior is automatically added.

WCF Web API–Elementary programming model

This is the first post on a series about the new Preview 4 of WCF Web API. In this post, I will start presenting the elementary aspects of the programming model.

Service classes/Resource classes and operations

It all starts with a class annotated with the ServiceContractAttribute attribute, usually called the resource class. In the WCF Web API, this class is just a container for methods that will handle HTTP requests for a set of related URIs. In WCF terminology, these methods are called operations.

As an example, consider the management of a “to do” list. A resource class for such scenario will typically contain methods/operations to handle the following HTTP methods:

  • GET the “to do” list;
  • POST a new “to do” into the list;
  • GET a specific “to do”;
  • DELETE a specific “to do”;
  • PUT an update to an existing “to do”.

This results in the following class.

    [ServiceContract]
    class TodoResource
    {
        [WebGet(UriTemplate = "")]
        HttpResponseMessage GetAllToDos(){...}

        [WebInvoke(UriTemplate = "", Method = "POST")]
        HttpResponseMessage PostNewTodo(HttpRequestMessage req){...}

        [WebGet(UriTemplate = "{id}")]
        HttpResponseMessage GetToDo(int id){...}
        
        [WebInvoke(UriTemplate = "{id}", Method = "DELETE")]
        HttpResponseMessage DeleteToDo(int id){...}
        
        [WebInvoke(UriTemplate = "{id}", Method = "PUT")]
        HttpResponseMessage UpdateToDo(int id, HttpRequestMessage req){...}        
    }

Association between HTTP requests and Operations

The association between an HTTP request and the operation  that will handle it is done via the WebGetAttribute and WebInvokeAttribute attributes. Notice how each method in the above class is annotated with one of these attributes.

The association uses two properties of a HTTP request:

  • The request URI;
  • The request method (e.g. GET, POST)

The WebGetAttribute associates the annotated method to requests with GET method and an URI that matches the WebGetAttribute .UriTemplate property.

The WebInvokeAttribute associates the annotated method to requests with a HTTP method contained in the WebInvokeAttribute.Method property, and an URI that matches the WebGetAttribute.UriTemplate property.

Operation Parameters

A resource class doesn’t have to derive from any class or interface. This means that there isn’t any language contract that an operation method must implement. Namely:

  • Operation methods can have any name;
  • The parameters and return type of an operation method are not defined by a base class or interface.

Instead, we can see the operation parameters as dependencies that WCF will try to resolve during runtime, using information derived from the request. In future posts, I will describe how this resolution is performed and how it can be extended.

Similarly, there isn’t any language contract specifying the return type of an operation. Instead, the WCF runtime will try to use the operation’s return value to build a HTTP response.

This absence of language contracts means that errors are not caught at compile time. Instead, if the operation parameters cannot be resolved, an error will occur only at service startup.

The HttpResponseMessage class

One of the return types allowed for an operation is the HttpResponseMessage type, which is a strongly typed representation of an HTTP response.

For instance, the GetAllToDos operation,  which handles a GET over the “to do” collection, uses it to completely control the response.

[WebGet(UriTemplate = "")]
HttpResponseMessage GetAllToDos()
{
    return new HttpResponseMessage()
    {
        StatusCode = HttpStatusCode.OK,
        Content = new StringContent(
            String.Concat(_repository.All.Select(t => t.ToString())))
    };
}                  

Notice the following:

  • The StatusCode property is of of type HttpStatusCode, which is an enum containing all the standard status codes.
  • The response body is controlled via the Content response property. In this case, a string type content is used (StringContent class), which results in a “text/plain” media type.

The HttpRequestMessage class

One of the accepted operation parameter types is the HttpRequestMessage, which is a strongly typed representation of a HTTP request.

For instance, the PostNewToDo operation uses this type as a parameter to obtain the “to do” representation from the request body

[WebInvoke(UriTemplate = "", Method = "POST")]
HttpResponseMessage PostNewToDo(HttpRequestMessage req)
{
    var body = req.Content.ReadAsString();
    dynamic formContent = FormUrlEncodedExtensions.ParseFormUrlEncoded(body);
    string description = formContent.Description;
    if (description == null)
    {
        return new HttpResponseMessage()
            {
                StatusCode = HttpStatusCode.BadRequest
            };
    }
    var td = new ToDo(description);
    _repository.Add(td);
    var response = new HttpResponseMessage();
    response.StatusCode = HttpStatusCode.Created;
    string uriString = req.RequestUri.AbsoluteUri + "/" + td.Id.ToString();
    Uri uri = new Uri(uriString);
    response.Headers.Location = uri;
    response.Content = new StringContent(uri.AbsoluteUri, Encoding.UTF8, "text/uri-list");
    return response;
}

Notice:

  • The parsing of the request into a dynamic object;
  • If the body does not contain a “description”, then a “Bad Request” response is returned;
  • If the new “to do” is successfully created, then a “Created” response is returned with a “Location” header containing this new “to do” URI.

UriTemplate variables

An operation can also have parameters whose names equals an URI template variable. For instance, the GetToDo operation uses this feature to obtain the “to do” identifier.

[WebGet(UriTemplate = "{id}")]
HttpResponseMessage GetToDo(int id)
{
    ToDo td = _repository.All.Where(t => t.Id == id).FirstOrDefault();
    if (td == null)
    {
        return new HttpResponseMessage()
        {
            StatusCode = HttpStatusCode.NotFound
        };
    }
    return new HttpResponseMessage()
    {
        StatusCode = HttpStatusCode.OK,
        Content = new StringContent(td.ToString())
    };
}

Notice:

  • The id parameter, that will be bound to the id variable on the “{id}” URI template.

The HTTP protocol as a first class concept

The initial version of WCF was heavily based on the SOAP model, where HTTP is just one of the available mechanisms to transport SOAP messages. The transport independence of the SOAP model means that the transport mechanisms are, for the most part, abstracted away behind a binding. 

However, WCF Web API aims to provide a “first class experience” for using HTTP. This means exposing HTTP as a transfer protocol in its full glory and not hiding it.

The use of the HttpRequestMessage and HttpResponseMessage types, as parameter and return type of the operations, are a way of giving direct access to the HTTP protocol, without some of the parsing and encoding complexity.

Notice also that the HTTP request information is explicitly passed into an operation as an HttpRequestMessage and not obtained from the “current context" (e.g. WebOperationContext.Current on previous versions of WCF).

The HttpRequestMessage and HttpResponseMessage classes belong to the Microsoft.Net.Http and are not dependent on WCF. Namely, these classes can be easily instantiated without having to use any WCF artifact.

These two aspects are essential for the operation testability, as we shall see in future posts.

The full code for this example can be found at github.

In the next post, I will describe how to host this service class/resource class.

WCF Web API–Preview 4

At PDC 2010, Glenn Block announced a new WCF based library for building Web based Application Programming Interfaces (API) – the WCF Web API. One of it goals is to provide a “first class experience” for using  HTTP. The first preview of this library, including source code, was published at http://wcf.codeplex.com.

This week, at MIX 11, the WCF Web API Preview 4 was finally published, providing a more matured programming model and implementation. The source code is also available on a Mercurial repository. To clone it, just do hg clone https://hg01.codeplex.com/wcf.

In the next posts, I will present an overview of this new WCF library.

Note: Preview 5 was released on September, 2011. The next posts and demos are based on this new release.