I spent a good chunk of the last year putting together a couple of different implementations of OAuth for internal use by our web services, and for some admin UI interfaces. The architecture guys were trying to push other development teams besides ours in that direction, too, so that we could have our services inter-operate, with a single security model.
Because I work in a large, multi-national corporation, nothing is that easy. There was lots of push back, and lots of opinions about how we should provide authorization around our web services and pages.
Or… lots of monkeys getting passionate about how to peel their bananas.
But one complaint that was kind of annoying was a standard rallying cry of the detractors that OAuth is not stateless. Ergo, it violates the principles of REST, and, ergo, is not consistent with the overall architectural direction.
So here is my take on that. I’m interested in what others think.
First, if the architecture team says, use REST, and then later they say use OAuth, it’s kind of silly to say the one rule disqualifies the other. Every technical choice is a series of considerations, and, one way or another, at the end of the day authorization and security concerns are going to trump just about anything else.
Second, how can you complain about OAuth’s state-ish-ness, and then turn around and put SSL in front of a REST service? I mean, come on.
However, ultimately, I’d like to come up with a better answer than “stop whining”, so I’ve been noodling on it some. Here’s what I think.
While the OAuth protocol is not stateless, because it requires the user to pass credenitals one time, and then maintain state of the user’s authorization on the server side, these are not considerations of the underlying HTTP protocol. It’s a higher-level concern. It’s the same as passing a “login” cookie or some other session token so the server can keep track of the user. Which is something we do all the time.
The point of statelessness is to make the servers on the REST side anonymous — so you can bring them up or tear them down at will, and leave the health of your service intact. If I have information held for clients on a particular box, and it goes down, then I have a problem, because all the client interacting with that box have lost their state.
But the kind of state that OAuth maintains is above the level of the HTTP protocol, and represents a generalization of an application concern. So really it’s not the individual *server* that cares about your OAuth token, it’s the *application* that cares.
Which means you can push your OAuth token into a distributed cache like memcached, and your individual servers are safe. OAuth, while it requires a sort of “session” state, doesn’t affect the state of any particular server, and doesn’t force you to provide server affinity.
In other words, yes, OAuth is stateful, but not the way you’re worried about. It doesn’t require the RESTful servers to be stateful.
In our implementation, we really quickly gave up on providing OAuth as a solution inside the application code itself, and almost all of our REST services externalize OAuth. For incoming traffic we use a reverse proxy in front of the service, and on the way out we use a regular proxy going to remote services. The “in” guy provides validation and bounces any unauthorized requests before they get to the REST server. The “out” guy adds the necessary headers to any outgoing request to satisfy OAuth.
That’s even nicer than terminating SSL in our load balancers, and I don’t hear anyone complaining about that.
I suppose I’ll have to continue scowling at the smug faces of developers who are convinced they’ve defeated OAuth with logic, but really I don’t see a problem with OAuth in a stateless server world.
Probably there’s a more concise way to put it, though, and I’d love to hear that.
So, to be clear, OAuth works well with REST, and doesn’t compromise any REST-ful-ness requirements for a server.
There are two ways to look at it:
+ authorization is part of the application concern, and part of a resource definition. Remember that the definition of Resource is arbitrarily large. So, “A list of ___ as allowed in this authorization scope.”
+ as a transparent concern provided by middleware, exactly as SSL (or even TCP) is. SSL doesn’t compromise the statelessness/REST-ful-ness of a service, despite it’s stateful protocol. One of the fundamental ideas of REST is to line up services in a way that allows dropping middleware in the flow to take care of concerns like routing, load balancing, encryption, authentication and authorization, without compromising the reliability of scalability of a resource server.
So OAuth, or really any token-passing authorization scheme, doesn’t compromise the validity of a REST service that it protects. You aren’t required to use Basic Auth, or proscribe SSL, everywhere to defend the REST-ful-ness of your service.
(However, statelessness is a good idea in itself … but the bigger issue for REST is that very few teams are implementing hypermedia in their service, so hardly anyone is implementing REST anyway.)