I’m happy to report that we’ve fixed an issue in the percent encoding step of our OAuth signature library for the Jersey framework. The issue reported was caused by the fact that we were using Java’s URLEncoder and URLDecoder classes to compute OAuth’s signature base string. Unfortunately those classes do not perform an RFC3986 compliant encoding which is required in OAuth. The main difference is that a space character will be encoded as a + when we need it to be escaped as a %20 (more info here).

To fix this, we’ve chosen to leverage Jersey’s UriComponent class. There is one notable difference though with how one would encode a URI (see here for a very detailed explanation of URIs): OAuth says that the signature base string is built by concatenating the request method, the request URL and the normalized parameters (with & to separate them) and that those elements must be encoded (prior to concatenation). In effect we are re-encoding elements that are already encoded. As Paul noted, it’s as if we wanted to pass the signature base string in a URI… I remember this possibility was mentioned in conversations about debugging OAuth deployment but that’s the only case I remember for this.

Anyway, to illustrate this, below is the piece of code where the bulk of the action happens:


StringBuffer buf = new StringBuffer(request.getRequestMethod().toUpperCase());
URI uri = constructRequestURL(request);
String tp = uri.getScheme();
buf.append('&').append(UriComponent.encode(tp, UriComponent.Type.SCHEME));
tp = uri.getAuthority();
buf.append("%3A%2F%2F").append(UriComponent.encode(tp, UriComponent.Type.AUTHORITY));
tp = uri.getPath();
buf.append(UriComponent.encode(tp, UriComponent.Type.PATH_SEGMENT));
buf.append('&').append(UriComponent.encode(normalizeParameters(request, params), UriComponent.Type.QUERY_PARAM));

Our testing code now also includes elements with spaces to make sure we got it right (thanks to Michael Werle).

Advertisements

Yesterday, I attended the OAuth BOF that took place during the IETF meeting in San Francisco. My participation was virtual though, since I was not physically there but thanks to live mp3 coverage and a chat room it was actually possible to follow the discussions and ask questions – very nice.
There were lots of discussions addressing several areas; here’s my recollection on the main points that were discussed:

  • Interoperability: what elements do people think are must-haves to ensure interoperable implementations of the IETF OAuth specification? Mandating a minimum set of signature algorithms (yes!).
  • Backward compatibility: although very important, we should not prevent ourselves from changing key aspects of the specification for the sake of backward compatibility. This is especially true for security issues. Of course, when not essential, changes that would break compatibility will be discarded.
  • Items to be worked on: via the chat room (see log here), I asked if the 2-legged scenario could be considered as relevant to this specification (the 2-legged case is when the service consumer is equivalent to the principal. In other words, we only have 2 parties involved in the transaction). To my satisfaction, many people agreed and so, after a hum in the room passed, it was agreed to include that use case in this work.
  • Charter: although the goal was to not change it, 2 important modifications will be made: integrate the 2-legged scenario and water down the compatibility constraints.

Overall I think this was a good meeting and we now have an official OAuth working group at IETF (well, once the normal process is completed).