Monday, October 10, 2011

Cross-Origin Resource Sharing and Authentication

Cross-Origin Resource Sharing (CORS) is a nice newish technology that allows you to throw off the shackles of JSONP. To give you a taste, it allows these things:
  • Proper error handling instead of waiting for some timeout.
  • Ability to post arbitrary amounts of data.
  • No helper libraries or crazy code required.
  • Uses standard XmlHttpRequest (or XDomainRequest for IE8+).
  • Basic Authentication (for non-IE browsers)
Feel free to ignore this paragraph, but before I proceed, I just wanted to talk at Microsoft about XDomainRequest. There was no need to introduce the entirely new XDomainRequest. You only needed to introduce restrictions on XmlHttpRequest in certain cases, just like all the other browsers do. I hope you at least add proper cross-origin support to XmlHttpRequest, if not fully deprecating XDomainRequest, in the future.

Regarding XDomainRequest, I also find the lack of ability to set headers quite unfortunate. This basically means that authorization information needs to be passed as part of the core message, which forces a generic API provider to rip out the authorization from the message and reformulate it into a generic message for the normal API framework to process. Specifically, this makes it impossible to send OAuth headers. Note that while you could include the auth token in the url, this has the danger of leaking into logs.

Okay, let's get into the meat of this post. I was searching for a way to authenticate access to a REST API. Since the browsers I cared about supported authentication, I thought I would just follow the web standards and use regular authentication.

Besides being a massive pain to get going with WCF or an HttpListener, I later discovered what I thought was a serious security flaw. If you allow all domains to access the REST API (which is important) then browser caching of authentication is a serious issue. For example, you visit site A, authenticate to shared service S, and then visit malicious site B. Malicious site B accesses shared service S and since your browser has cached the credentials for S, it magically logs in and allows B to access the restricted content.

Well, it turns out the browser authors are smarter than me and they disallow authentication when allowing access to arbitrary domains. Herein lies the crux of design improvement #2 that I found myself wishing for. When you perform a request using XmlHttpRequest, you specify the credentials in the call to open(). Why couldn't the API simply not cache those credentials if accessing a CORS site with "*" for the domain restriction?

Okay, I've taken you through my journey. What's a REST API author to do for authentication? Well, since the browser is inept at managing to keep its data to itself, it seems we need to do it for it. As far as I can tell, cross-origin requests requiring authentication must pass some sort of authentication information with each request. I haven't fully explored the best way to do this, but there are a variety of schemes from signing the message to session tokens to sending the username and password as part of the request. I've been exploring the options here and I'll post more on my findings in the near future.

I'd be happy to hear if I missed anything, but I'm pretty sure I understand how lame the situation is. Well, at least it's not JSONP.

How Not To Make Passion Tea

I have taken a liking to Starbuck's Iced Passion Tea (with or without lemonade). Since I'm just a poor business owner, I thought I would buy a box of their Tazo Passion Tea and try to make some myself. Unfortunately, every time I steeped the tea, it ended up being too bitter.

After several attempts, I had the thought that it was my brewing technique that was causing the bitter taste. I had originally been pouring the boiling water on to the tea bag in an attempt to extract maximum flavour. Unfortunately, this seems to also extract maximum bitterness. When I made a cup of tea and deliberately avoided pouring the water onto the tea bag, the tea came out fine.

I'm looking forward to finding a good sugar/syrup/lemonade combination next.

Wednesday, May 11, 2011

Vancouver Eats

I recently went on a trip to Victoria and Vancouver for about a week. Here are some memorable foods from the trip.

1. Peaceful Garden Restaurant had great lamb cumin noodles. Their noodles are freshly made and cut right before cooking. I'm normally not a big fan of lamb, but I really enjoyed it.

2. Honey's Cafe in Deep Cove. Besides being beautiful and a great place to kayak, Deep Cove holds a secret treasure. Donuts. Go to the cafe and order one. They only have one kind, but to compensate, your donut is warm, soft, and delicious. Mmmm.

3. Last but certainly not least is Jimmy's Fruit Bar in the Lonsdale Quay. Being in business for a number of years, Jimmy has invented quite a variety of tasty and healthy drinks. My favorite while we stayed there was a drink called "Mr. Green Lifesaver." It's a delightful combination of mint, kale, spinach, pear, and mango, among other things. Tasty and refreshing. I'd highly recommend stopping by this friendly place for a great drink or two.

Monday, March 21, 2011

The Shrinking DLL Universe of NHibernate

There have been some interesting changes in the NHibernate universe recently. It used to be that you needed a whole bunch of DLLs and some extra config to do anything useful with NHibernate.

  • NHibernate
  • Iesi.Collections
  • Antlr.Runtime
  • Remotion.Data.Linq
  • NHibernate.ByteCode.Castle
  • Castle.Core

As of NHibernate 3.1, Antlr and Remotion have been ILMerged into the main dll, producing this picture.

  • NHibernate
  • Iesi.Collections
  • NHibernate.ByteCode.Castle
  • Castle.Core

As of NHibernate 3.2, there's now a default lazy proxy provider based on LinFu (thanks Philip). As well, this proxy provider is configured automatically, reducing a line of config required. This produces an even nicer picture for most users.

  • NHibernate
  • Iesi.Collections

Now we just need to replace Iesi.Collections with the .NET 4 ISet and we'll only have one dll to reference. I have no idea when that will happen, but it's an interesting thought anyways.

WPF Lazy Proxy Revisited for NHibernate 3.2

When hooking up to PropertyChanged events, some systems require that the same object that a handler was registered with be the same object that throws the event. With NHibernate proxying, this can be a problem. The external viewer normally hooks up to the proxy object, but then the actual implementation object is the one throwing the property changed event, using "this" as a reference, which is naturally different from the proxy. This behavior occurs because the proxying is not entirely transparent. Even though the user hooks up to the proxy object and expects events from the proxy object, the real object throws the events, messing with handlers that may be stored in dictionaries mapped by the sender. See my first post for other details on this same problem.

The original solution to this problem modified the Castle bytecode provider. Now, with NHibernate 3.2, there is a default provider built-in. Here is the new code with the fix for the PropertyChanged event. Using this code fixes problems with WPF and libraries like Obtics.