April 2009 - Posts

OpenRasta (OR) is the name of a new open source framework for developing Restful applications (Web applications or services) created by Sebastien Lambla. As the ASP.NET MVC, this framework is also an implementation of the MVC pattern, which focus mainly on a good separation of concerns, and provide different extensibility points where the developer can plugging custom code at the moment of developing applications.

The framework is now on Beta 2 stage, Sebastien and other guys are currently working on improving the hosting infrastructure and public API. They are, of course, very open at this point to receive feedback or suggestions for new features, or improvements to existing ones. If you have some interest in participating of this project, you can start joining the mailing list.

In order to understand how OR works under the hood, I will start by describing some basic concepts that a developer should know to implement an application from scratch with this framework.

Handlers

A “handler” is one of the main building blocks in OR. It represents the implementation of the service itself, and it is generally mapped to single resource through an URI. Therefore, any access to an URI will get resolved by OR to an specific handler.

From an implementation point of view, a handler is simple class that expose methods for handling different http verbs. By convention, a method should be called as the Http verb that supports, for example, Get or Post. However, nothing prevent you from giving more friendly names to the methods (or handler operations), there is an special custom attribute “HttpOperationAttribute” that you can use to associate the method with an http verb.

public class CustomerHandler

{

    public Customer Get(int customerId)

    {

        return new Customer { FirstName = "foo", LastName = "bar" };

    }

    public OperationResult Put(int id, Customer customer)

    {

        return new OperationResult.Modified { ResponseResource = customer };

    }

    [HttpOperation(HttpMethod.POST)]

    public OperationResult MyFriendlyMethod(int id, Customer customer)

    {

        return new OperationResult.Modified { ResponseResource = customer };

    }

}

If you want to have a better control of the Http status code, as it is shown in the code above, you can also return an instance of OperationResult.

Codecs

As you can see, the handlers have not been wired to any content type at this point. Serializing/Deserializing a resource instance into an specific representation is responsibility of the codecs. Some codecs are provided out of the box in OR, for example, Json, Xml, Html or Form-Url-Encoded data.

A codec generally implement two interfaces, IMediaTypeReader (for deserializing content) and IMediaTypeWriter(for serializing). The following code shows the implementation of the Json codec,

[MediaType("application/json;q=0.5", "json")]

public class JsonDataContractCodec : IMediaTypeReader, IMediaTypeWriter

{

    public object Configuration { get; set; }

    public object ReadFrom(IHttpEntity request, System.Type destinationType, string paramName)

    {

        DataContractJsonSerializer serializer = new DataContractJsonSerializer(destinationType);

        return serializer.ReadObject(request.Stream);

    }

    public void WriteTo(object entity, IHttpEntity response, string[] paramneters)

    {

        if (entity == null)

            return;

        DataContractJsonSerializer serializer = new DataContractJsonSerializer(entity.GetType());

        serializer.WriteObject(response.Stream, entity);

    }

}

Putting Handlers and Codecs together

By means of a fluent configuration, we can later wire up an URI with the corresponding handler and one or more codecs according to the content-types that the service should support.

ConfigureServer(() => ResourceSpace.Has.ResourcesOfType<Customer>()

                          .AtUri("/customer/{id}")

                          .HandledBy<CustomerHandler>()

                          .AndTranscodedBy<OpenRasta.Codecs.JsonDataContractCodec>()

                          .AndBy<OpenRasta.Codecs.XmlSerializerCodec>());

This is one of the big differences with the ASP.NET MVC or the Web Programming Model in WCF.

In the MVC, the supported content types are inherently tied to the ActionResult returned by the controller action. Therefore, the action implementation must be modified in order to support new content types.  Or a more specialized implementation of an ActionResult is required, which has to be smart enough to accommodate these changes.

Same thing happens with WCF, you have to either decorate the service operation with the supported content-type (Only Json or Pox supported today) or return a Message/Stream instance from the operation and write the resource representation yourself in the operation implementation. As I said, only Json/Pox are supported today, and adding new content types is something complicated to do. You basically need to write a custom IDispatchMessageFormatter extension, and a custom WebServiceHost to replace the formatter provided out of the box. (This is the approach taken in the WCF REST Starter kit for supporting form-url-encoded data).

Pipeline Contributors

Let’s go back to OpenRasta for a moment, “Handlers” and “Codecs” are not the only supported extensibility points in this framework. All the processing of incoming/outgoing messages is performed in a pipeline that contains contributors or filters. A pipeline contributor perform simple tasks such as initializing the security context, routing the messages or processing exceptions to name a few. You can write your own contributors, or customize the pipeline to support different configurations or scenarios

More information about OpenRasta 

You can find more information about this framework in the Sebastien’s blog. The current project status is also available here.

Posted by cibrax | 1 comment(s)
Filed under: , ,

Many of the features available out of the box today in the ASP.NET MVC framework are only intended to develop web applications using REST principles. There is not support for accepting incoming messages encoded as JSON or plain old XML (POX), or even support for returning POX from a controller action. Only form-urlencoded data is accepted by default for incoming messages, and JSON/HTML (with support of the view engines) for outgoing messages in controller actions.

However, thanks to the different extensibility points that the MVC provides for hooking up custom code, supporting different scenarios for RESTful services tend to be something really easy to implement.

In this framework, we basically have two extensibility points that deserve some attention, Action Filters and Action Results.

Action filters intercept messages before they are dispatched to the controller action (or operation), and just after the operation returns a result. They are basically equivalent to the Dispatch Message Interceptors in WCF, or the new Message Interceptors in the WCF REST Starter kit (although they work more at a deeper level in the WCF processing pipeline).

Action results know how to serialize and write an object (the controller action result) into the response stream. Since they also have access to the Response object, additional work can be done there to manipulate some response settings or add output headers.

The framework also support Model Binders, which basically knows how to create an object representing the model expected by the controller action from some scalar values. Those scalar values are parsed from the incoming message (encoded as form-urlencoded), and then passed to the binder. However, they do not seem to add any value for implementing RESTful services with support for JSON or XML.

Omar Al Zabir has already written an nice post on how to implement RESTful services with the ASP.NET MVC that speak JSON and XML using action filters and action results.

ATOM and other syndication formats can also be handled as XML. For this, the Web Programming Model in WCF comes with a couple of classes, Rss20FeedFormatter and Atom10FeedFormator, which are Data Contracts and also IXmlSerializable classes. Therefore, if your operation returns an instance of any of these classes, the filters created by Omar would address this scenario as well. Regarding Conditional get support, you will have to implement it in the action itself or a custom filter. (You will have to do the same thing if you decide to go with the WCF Web Programming Model).

Caching is another feature that you might want to use at the moment of developing RESTful services. Fortunately, the MVC also comes with an special action filter “OutputCache” that was built on top the ASP.NET cache, so it provides the same caching capabilities that you may use for normal ASP.NET pages.

Posted by cibrax | 2 comment(s)
Filed under: , ,

Aqui pueden encontrar el material de la prestacion que di en el dia de hoy acerca de construccion de web services con ASP.NET y WCF en Visual Studio 2008.

Posted by cibrax | 5 comment(s)
Filed under: ,

When Mutual Certificate Authentication is configured for REST services, both, the client and the service perform identity verification or authentication through X509 certificates.

The client authenticates the service during the initial SSL handshake, when the server sends the client a certificate to authenticate itself. More information about this process can be found here.

The service on the other hand, performs similar validations on the certificate attached by the client consumer to the request message.

Some specific configuration settings are required in WCF to use this authentication scenario with REST services. The service must be configured with transport security (SSL), “certificate” as client credential type.

<webHttpBinding>

  <binding name="mutual">

    <security mode="Transport">

      <transport clientCredentialType="Certificate"/>

    </security>   </binding>

</webHttpBinding>

For example, the complete configuration for a REST service that provides ATOM feeds would be the following,

<system.serviceModel>

  <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>

  <services>

    <service name="MutualAuthenticationRest.FeedService">

      <endpoint address="" contract="MutualAuthenticationRest.IFeedService" binding="webHttpBinding" bindingConfiguration="mutual" behaviorConfiguration="mutual"></endpoint>

     </service>

  </services>

  <bindings>

    <webHttpBinding>

      <binding name="mutual">

        <security mode="Transport">

          <transport clientCredentialType="Certificate"/>

         </security>

       </binding>

     </webHttpBinding>

    </bindings>

    <behaviors>

      <endpointBehaviors>

        <behavior name="mutual">

          <webHttp/>

        </behavior>

     </endpointBehaviors>

   </behaviors>

</system.serviceModel>

The virtual directory used for hosting the service in IIS must also be configured with the same security settings.

MutualCertificate

The client application only need to attach the certificate at the moment of consuming the service. This can be easily done with the new HttpClient class shipped as part of the WCF REST Starter kit,

class Program

{

    static void Main(string[] args)

    {

        X509Certificate2 certificate = CertificateUtil.GetCertificate(StoreName.My, StoreLocation.LocalMachine, "CN=clientCert");

        HttpClient client = new HttpClient();

        client.TransportSettings.ClientCertificates.Add(certificate); //Cert attached to the request

        string content = client.Get("https://localhost/MutualAuthentication/Service.svc?numItems=10").Content.ReadAsString();

        Console.WriteLine(content);

    }

}

CertificateUtil is an helper class that looks for an specific X509 certificate in the windows certificate store. In addition, if you are using test certificates, you might want to disable the service authentication on the client side, that can be done with a callback attached to the static class “ServicePointManager”.

For instance,

public class PermissiveCertificatePolicy

{

    public static void Enable()

    {

        ServicePointManager.ServerCertificateValidationCallback +=

           new RemoteCertificateValidationCallback(RemoteCertValidate);

    }

    static bool RemoteCertValidate(object sender, X509Certificate cert, X509Chain chain, System.Net.Security.SslPolicyErrors error)

    {

        return true;

    }

}

The method PermissiveCertificatePolicy.Enable should be called before consuming the service.

Posted by cibrax | 8 comment(s)
Filed under: , ,

It is very common for WCF services that work as Ajax callbacks and ASP.NET pages that live in the same web application to share a common security context for the authenticated user. However, in order to make this happens, the ASP.NET compatibility mode must be enabled for the WCF service. When that setting is enabled, WCF basically includes the service call within the ASP.NET pipeline, all the ASP.NET modules configured for the application are executed, and as result, the HttpContext get initialized for that service as it was a normal page. 

Optionally, an IAuthorizationPolicy can be used to inject the HttpContext.User into the WCF security context, and completely decouple in that way, the service implementation from the Http security context.

For example, we can have a web application configured with Forms Authentication or the new FederationModule in geneva framework for authenticating users with passive federation, and share that security context with the services or ajax callbacks that the web pages consume.

For this scenario, the WCF REST Starter kit already includes an IAuthorizationPolicy implementation for initialization the WCF security context with the authenticated user in the web application. That authorization policy is automatically injected in the service execution pipeline by the WebServiceHost2 host shipped also within the kit. If you are using that WCF host, you do not have to do anything extra other than enabling the ASP.NET compatibility mode for the services.

Configuring the ASP.NET compatibility mode requires two steps.

1. Add a configuration settings in the configuration file,

<system.serviceModel>

<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />

</system.serviceModel>

 2. Add support for this mode in the service implementation. This is done through an special attribute “AspNetCompatibilityRequirements” added to the class definition

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)] 

[ServiceContract]

public class ClaimsService

Once you have done that, the user principal will become available to the service through the WCF security context or the Thread.CurrentPrincipal property.

Posted by cibrax | 1 comment(s)
Filed under: , ,

I just got great news!  MVP in Connected Systems for another year.

I want to thank Ed Hickey, my MVP lead Fernando Garcia Loera, and the rest of people involved in the evaluation process for once again considering my efforts in the community worthy of recognition.

Thanks again Microsoft!!!

Posted by cibrax | 2 comment(s)
Filed under: , ,

Some people have been asking around in the MSDN forums or stackoverflow about a possible way to pass form-urlencoded data to an existing WCF REST service. Although this is not a core feature in WCF from my point view, there is still some support for addressing this scenario in the REST Starter kit.

This feature takes the form of a new message formatter, FormsPostDispatchMessageFormatter, which is automatically injected to any existing service hosted within the new WebServiceHost2 host (shipped as part of the kit)

This formatter basically intercepts all messages, and handle those that contains “application/x-www-form-urlencoded” as content type in the request header. The rest of the messages are handled by the existing formatters as usual.

The service operation must expose a NameValueCollection argument in the method signature in order to receive the data. This collection will contain the key/value pairs that were parsed from request body.

For example,

[WebInvoke(UriTemplate = "SetData")]

[OperationContract]

void SetData(NameValueCollection formsData)

{

    this.value = Int32.Parse(formsData["counter"]);

}

“Counter”  in this case represents a field in the form that was posted to the service.

<

FORM action="service.svc/SetData" method="post">

Input Counter value and hit enter:

<INPUT type="text" name="Counter">

</FORM>
Posted by cibrax | 1 comment(s)
Filed under: , ,
More Posts