Brain Flush

March 21, 2010

Signpost 1.2.1.1 maintenance release

Filed under: Software Development & Programming — Tags: , , , — Matthias @ 11:46 am

Sorry for any inconvenience caused by the Signpost 1.2.1 release last week, which apparently regressed on callback URLs (see issue 34). That’s fixed in 1.2.1.1, along with another bug which prevented custom OAuth authorization headers to not be correctly interpreted before message signing.

Both should work fine now.

Have a nice weekend!

Advertisements

March 13, 2010

Signpost 1.2.1 released: fixes and features inside!

Filed under: Software Development & Programming — Tags: , , — Matthias @ 10:23 pm

I just released Signpost 1.2.1, which is mainly a maintenance release, but also contains a couple new features.

Here is what changed:

  • OAuthProvider has become more flexible. You can now override even more of its default behavior, e.g. for creating customized requests for the token handshake. I’ve also reduced code duplication by pulling code up from concrete provider implementations to the abstract base class, so you now only need to worry about implementing small, self-contained steps when implementing a custom provider, such as creating a custom request object.
  • OAuthProvider now sends token requests using POST, as suggested by the standard. You can change that behavior by overriding createRequest(endpointUrl), but that should hardly be ever required.
  • OAuthProviderListener is a new class that allows you to hook into the token handshake and intercept the flow at certain points (e.g. before and after message signing). This makes it easy for you to customize the request that is being sent, e.g. by setting custom headers or parameters. This deprecates setRequestHeader(), which was formerly used to do that, but which was very limited.
  • During token handshake, OAuth parameters are no longer being sent in a “mixed” way, i.e. they all go in one place now, depending on which SigningStrategy is used by the consumer. In earlier versions, OAuthProvider would always send the oauth_callback and oauth_verifier in the URL.
  • CommonsHttpOAuthProvider can now be configured with a custom HttpClient
  • During token handshake, unsuccessful server replies (e.g. 401 or 400) are not being swallowed anymore, instead the response body can now be retrieved from the exception that is thrown and be interpreted by the client.
  • The debug output has been extended to include the Authorization header and request URL (note that when using java.net.HttpURLConnection, one cannot read the Auth header for security reasons, and it will always print as null)

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!

June 14, 2009

Better OAuth for Java: Signpost 1.1 comes in flavors!

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

Signpost, my client-side OAuth library for Java, now comes modularized, so that you can use it with other HTTP libraries than Apache HTTP Components.

By default, Signpost now only supports signing java.net.HttpURLConnection type requests, which makes the core module completely independent of any specific HTTP messaging layer. Instead, additional HTTP libraries are supported via add-on JARs; adapters have been created for Jetty HTTP 6 and Apache HTTP Components 4.

More info on the project website: http://code.google.com/p/oauth-signpost

May 3, 2009

Introducing Signpost: Easy OAuth for Java and Apache HttpComponents (Android, too)

Filed under: Software Development & Programming — Tags: , , , , , , , — Matthias @ 10:58 am

I would like to announce a project I started, which I hope may be useful to Java (particularly Google Android) application developers who need to communicate with web services that leverage the OAuth protocol for accessing protected resources.

What is Signpost?

Signpost is the easy and intuitive solution for signing HTTP messages in conformance with the OAuth Core 1.0 standard. Signpost has been designed to work in conjunction with the Apache HttpComponents library, a proven, well-established HTTP library for the Java programming language.

Signpost is still in beta stage, which means it may contain bugs. The project is currently hosted at Google Code and can be downloaded, distributed and used under the terms of the Apache License, version 2.

Why another OAuth library for Java?

It was my discontendness with Netflix’s OAuth implementation which ultimately drove me to develop my own solution. My biggest gripes with it were:

  • Its clumsy, overly complicated API
  • Its tendency to do more than what’s actually in the standard (why does it implement an own HTTP layer? OAuth is about message signing, not about message sending)
  • Its limitations resulting from the last point, particularly:
    • Its ignorance towards RESTful web services (a 201 is treated as an error)
    • Its inability to process other HTTP verbs than GET (you must subclass in order to POST or PUT a resource)
    • Its inability to send more complex messages (don’t even try to send multipart requests)

Signpost attempts to avoid these issues as described below (a brief remark: Despite those issues, I highly appreciate Netflix’s work on the original implementation. In fact, Signpost is to some degree based on code from the reference implementation).

Goals of Signpost

Signpost has been designed with several principal goals in mind:

Simplicity

Using Signpost is as simple as it could possibly get — all actions are executed with only a few lines of code. For example, here is how you would sign an HTTP message using Signpost (assuming you have already created the involved HttpClient and OAuthConsumer objects):

        // create an HTTP request to a protected resource
        HttpGet request = new HttpGet("http://example.com/protected");

        // sign the request (consumer is a Signpost OAuthConsumer)
        consumer.sign(request);

        // send the request
        HttpResponse response = httpClient.execute(request);

Signpost exposes a minimalistic API designed for two purposes: Signing HTTP messages and requesting tokens from an OAuth service provider. Everything else is beyond the scope of the OAuth specification, and is thus left to the HTTP messaging layer, where it belongs.

For more exhaustive examples, please refer to GettingStarted.

Unobtrusiveness

Signpost tries to be as unobtrusive as possible. Unlike the OAuth reference implementation for Java, Signpost does not wrap the entire HTTP layer and hides its features from the client. Instead, you simply pass an HttpRequest object to it, and Signpost will sign the message using the credentials it was configured with. This means that all the power and flexibility of the Apache HttpComponents? is still at your fingertips!

Limitations

Simplicity doesn’t come free. Thus, Signpost currently makes certain assumptions to reduce the complexity of both the implementation and the API.

Deviations from the OAuth standard

  • Additional service provider parameters for retrieving request tokens are currently unsupported (cf. section 6.1)
  • Message signing using public key encryption (as per section 9.3) is currently unsupported. Message signing using the PLAINTEXT and HMAC-SHA1 is supported, however.
  • The OAuth standard demands that OAuth request parameters may be put in the URI query string or in the message payload. Signpost will never do that; instead, all OAuth protocol parameters are written to the HTTP Authorization header field. Anything you put there will be overwritten by Signpost.
  • Signpost does not support writing OAuth protocol params to the WWW-Authenticate header field

I believe that even with those restrictions in place, Signpost will work for 99% of its users. Trading in some flexibility only relevant for edge cases was a design decision. If that doesn’t work for your setup, then Signpost is probably not the best choice.

Thread Safety

Signpost is not thread safe and probably will never be. Signpost objects are very lightweight, so you are adviced to create an OAuthConsumer and OAuthProvider for every thread in your application that must send signed HTTP requests.

Google Android

Signpost works flawlessly in conjunction with Android, Google’s software stack for mobile devices. In fact, Signpost has already signed thousands of HTTP requests at this very moment, as it is an integral part of Qype Radar, our geo-sensitive mobile application for Android that finds the best places near you.

Since Android already ships with a recent version of the Apache HttpComponents?, you merely need to add the Signpost JAR to your Android application, and you’re all set.

Create a free website or blog at WordPress.com.