Brain Flush

January 31, 2010

Signpost 1.2 released – now on Maven Central

Filed under: Software Development & Programming — Tags: , , , — Matthias @ 6:47 pm

I am happy to announce that I have released Signpost 1.2 earlier this week and I will briefly go over the changes the library has undergone. Most changes were under the hood, although there are also some minor API changes. I have rewritten much of the core code base, so as to make the library more flexible and easily extensible, something that was often requested by users.

Flexibility, extensibility, and general design improvements

I have flipped quite some bits in signpost-core, and now Signpost is finally more easily extensible and better configurable by developers. AbstractOAuthConsumer now lets subclasses override practically any step in the signing process, or even the entire signing altogether, by following the template method pattern. So if you need special treatment while collecting message parameters for signing, or want to use a different nonce generation algorithm, just override the respective methods in your subclass.

There is also a new class called SigningStrategy. This class defines how a signature is written to an HTTP request. The default behavior is to write OAuth parameters to the HTTP Authorization header (using AuthorizationHeaderSigningStrategy), but you can go ahead and create a custom strategy and configure your OAuthConsumer with it.

Speaking of customization. Should you be implementing your own OAuthConsumer, I have also improved the testability in that case tremendously. Simply inherit from OAuthConsumerTest and implement buildConsumer(). The test will then be executed for your particular consumer configuration.

There are also two API changes by which everyone will be affected. First, I have removed the SignatureMethod enum, since it was not very useful. Instead, every OAuthConsumer uses the HMac-SHA1 signature method by default, since that’s what everyone seems to be using anyway. So constructing a consumer is now simplified to:

OAuthConsumer consumer = new DefaultOAuthConsumer(CONSUMER_KEY,
                                     CONSUMER_SECRET);

If you really want to use a different signer, you can do this:

consumer.setMessageSigner(new PlaintextMessageSigner());

The second API change affects OAuthProvider. In earlier versions, consumer and provider were closely coupled. That led to problems in service oriented environments, where each object should be self-contained when exposed as a service. Thus, the retrieve*Token() methods of OAuthProvider now accept a consumer as the first argument:

String authUrl = provider.retrieveRequestToken(consumer, "http://example.com/callback");
// ...
provider.retrieveAccessToken(consumer, pin);

Android support

Signpost worked well on Android before, however, a bug in Android’s Java implementation (that would be Apache Harmony) prevented it to work correctly with certain service providers (HttpURLConnection is sending lower-case HTTP header names on Android, which breaks some server side OAuth implementations because they don’t recognize the Authorization header; see issue 20). I have therefore implemented a CommonsHttpOAuthProvider, which uses Apache HttpClient to receive tokens instead of HttpURLConnection.

New features

Signpost can now sign URLs. Just pass the consumer a URL string, and it will treat it as an HTTP GET message on the resource identified by the URL and append all necessary OAuth parameters to that URL. This can be very useful if you want to produce clickable links to protected resources:

String signedUrl = consumer.sign("http://example.com");

Another minor but useful feature is Signpost’s new debug mode. If you run your app with the -Ddebug flag, Signpost will now print the signature base string and generated signature for each request it signs to stdout. This is very useful when trying to figure out what went wrong should a server answer with 401 and you believe you did everything right:

[SIGNPOST] SBS: GET&http%3A%2F%2Ftwitter.com%2Foauth%2Frequ...
[SIGNPOST] signature: BVzjTYNjeJJwI4olm5ISHtvZ7Rc=

Bug fixes

Of course this release has seen some bug fixes, too. One of the most important ones is that Signpost does not send a blank oauth_token parameter anymore when retrieving a request token. Although permitted by the standard, and although many providers like Twitter or Google accept this, certain other providers failed when doing so (e.g. Netflix). If you still want to get the old pre-1.2 behavior, call setSendEmptyTokens(true) on your consumer.

Another important fix/enhancement corrects the way Signpost used to write to the Authorization header. Previously, it would just overwrite it with the OAuth parameters it generated, which caused problems when client needed to provide a realm paramter in the Auth header alongside the OAuth params. Signpost now remembers what had been in the Authorization header prior to message signing, appends its own params to it, and writes all of them back to the header. This should get rid of 401s where service providers expect a security realm to be set.

Finally, a problem was corrected where x-www-form-encoded body params were ignored if the content type contained parameters like encodings.

Project reports / API docs

I have also finally uploaded the API docs and other project reports generated by the Maven site plugin to GitHub pages, so you can browse the API docs without linking the JavaDoc JAR. You can find all project reports and other generated information here: http://kaeppler.github.com/signpost/project-reports.html

Maven Central

Last but certainly not least: Signpost 1.2 is now available via Maven Central, which means you do not have to add the signpost-releases repository to your POM anymore. It is available straight away in any Maven powered Java project. Om nom!

About these ads

5 Comments »

  1. Hi Matthias-

    Just wanted to say thanks for all your work on signpost. It’s my favorite kind of library- small, focused, with few dependencies, written by one person. When I was looking for an oauth library to help us get going quickly with some integrations, I was initially dismayed at the larger, bulkier projects out there- they all seemed messy, and I wasn’t enthusiastic about adding them to our carefully composed tech stack. (In particular, we use Restlet instead of the Servlet api, which many libraries presume is present). I was just about ready to decide to implement oauth integrations from scratch when I found signpost.

    So, thanks very much!

    -Dave Fogel

    P.S. although we haven’t found it necessary yet (we’re just using the default impl), I’m considering writing a signpost plugin for Restlet client http requests. I’m certainly willing to contribute it to signpost if I end up writing it…

    Comment by carrotsalad — February 7, 2010 @ 6:58 pm

    • Hey thanks, good to hear it works well for you! Send anything along what you think may add value to the library, that’s why it’s open source after all :-)

      Comment by Matthias Käppler — February 7, 2010 @ 7:54 pm

  2. Hi Matthias,

    Do the OAuthConsumer and OAuthProvider thread safe ? I am planning to make them as a singleton object in my controller class ?

    Regards.

    Comment by zainul franciscus — March 2, 2010 @ 12:30 pm

    • Signpost in general is not thread-safe. That doesn’t necessarily mean that all parts of it aren’t thread-safe, however. I just haven’t put enough thought into into that topic yet. I assume OAuthConsumer could be made thread-safe with very little effort, since it’s practically stateless. OAuthProvider is another story. It has to maintain state across token requests, which are vulnerable to race conditions and lost updates / dirty data, so it would have to be synchronized to work in concurrent environments.

      I don’t see me working on this anytime soon, since there is practically no demand for it. If you’re using singletons, I’d rather ask myself if you chose the right design (In 98% of the cases, I would immediately object against using singletons, since it’s the most abused “design pattern” ever). Signpost objects are very lightweight (object footprint is negligible, even in low memory environments such as mobile devices), the bulk of its memory consumption comes from dependent classes, which you have to load anyway. Hence, I’d strongly suggest you either create Signpost objects on a per-thread basis, or synchronize their use with Java’s locking facilities.

      Comment by Matthias Käppler — March 2, 2010 @ 1:54 pm

  3. Hm.. Please update examples on http://code.google.com/p/oauth-signpost/
    They use SignatureMethod, but library without it.
    Thanx

    Comment by Viktor — December 28, 2010 @ 9:33 am


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Shocking Blue Green Theme. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 37 other followers

%d bloggers like this: