Do you have a web service that you'd like to set up authentication on? OAuth is a popular tool to accomplish this task. In this excerpt from Subbu Allamaraju's RESTful Web Services Cookbook you'll learn how to use three-legged OAuth authentication.
OAuth (http://oauth.net) is a delegated authorization protocol developed in 2007. Using this protocol, a user can, without revealing her credentials, let a client access her data available on a server. OAuth’s authentication protocol is called three-legged because there are three parties involved in the protocol: the service provider (i.e., the server), the OAuth consumer (i.e., the client), and a user.
OAuth’s three-legged protocol is applicable whenever a client would like to access a given user’s resources available on a server. For instance, users of Twitter, Yahoo!, Google, Netflix, etc., use the OAuth protocol to grant access to their data to third-party tools so that those tools can access a user’s data without asking users to share their credentials such as username and password. Implementations of this protocol are available in most programming languages.
Figure 12.1 shows the role of the OAuth protocol. At the start of the protocol, the server uses a “consumer key” as an identifier for the client and a“ consumer secret” as a shared secret. Once a user authorizes the client to access her resources, the server uses an “access token” as an identifier uses the authorized client and uses a “token secret” as a shared secret.
- Consumer key and consumer secret
The consumer key is a unique identifier for the client. The client uses the consumer secret to sign the request to obtain request tokens.
- Request token and token secret
The request token is a temporary one-time identifier issued by the server for the purpose of asking the user to grant permission to the client. The token secret is used to sign the request to obtain an access token.
- Access token and token secret
The access token is an identifier for use by the client to access the user’s resources. A client in possession of an access token can access the user’s resources as long as the token is valid. The server may revoke it at any time either due to expiry or due to the user revoking the permission. The secret is used to sign requests to access the protected user’s resources.
Using three-legged OAuth involves the following steps. The purpose of this flow is to obtain an access token and a secret. The server may grant the access token for a particular period of time and/or to limit access to certain user resources.
The client requests the server for a consumer key and a consumer secret out of band.
The client uses the consumer key to obtain a request token and a secret.
The client directs the user to the server to grant permission to let the client access the user’s resources. This process results in an authenticated request token.
The client requests the server to provide an access token and secret. These represent an identifier and shared secret that the client can use to access resources on behalf of the user.
When making a request to access a protected resource, the client includes an
Authorizationheader (or query parameters) containing the consumer key, the access token, the signature method and a signature, the timestamp, a nonce, and optionally the version of the OAuth protocol.
Note that since OAuth is a protocol layered on top of HTTP, servers need to document the following URIs to clients:
URI to obtain request token
URI to authorize the server
URI to obtain an access token
OAuth recommends using
POST to obtain request and
Consider the photo album web service introduced in the section called “How to Copy a Resource”. The
client needs the user’s authorization for it to be able to make a copy
of a user’s photo album resource. The client approaches the server to
oauth_consumer_key and a secret through some
out-of-band means. For example, the server may provide a web page for
clients to register and obtain the consumer key and consumer secret.
Assume that the server assigns
a1191fd420e0164c2f9aeac32ed35d23 as the consumer key and,
as the shared secret,
For the client to initiate the three-legged protocol, the server documents the following URIs:
Consider using TLS for these URIs since responses involve shared secrets and user authorization.
This is the signing method used when computing a signature. OAuth defines
RSA-SHA1as the signing methods. When clients and servers are using TLS, you can avoid signatures and use
PLAINTEXTas the value of this parameter.
This is a random string that is unique for all requests sent at a given
oauth_timestamp. This parameter helps servers deter replay attacks. Note that, unlike digest authentication, OAuth requires clients to generate nonce values.
Clients can send these parameters as directives of the
Authorization headers, or query parameters, or encoded
application/x-www-form-urlencoded in the body of
the request. The following examples use the
header for all requests.
The first step for the client is to submit a request to obtain a
request token and a secret from the server. The signature in this
request is based on the consumer secret that the client obtained along
with the consumer key. The signature includes
oauth_version and must be computed as
Percent-encode the parameters, and sort them first by their name and then by their value.
Concatenate the parameters into a string just the way you compute an
application/x-www-form-urlencodedstring. For this example, the value of this string is
Compute a signature using the shared secret. For this example, the signature is
Base64-encode the signature, and then percent-encode the resulting text.
# Request to obtain a request token POST /request_token HTTP/1.1  Host: www.example.org Authorization: OAuth realm="http://www.example.com/photos", oauth_consumer_key=a1191fd420e0164c2f9aeac32ed35d23, oauth_nonce=109843dea839120a, oauth_signature=d8e19bb988110380a72f6ca33b2ba5903272fe1, oauth_signature_method=HMAC-SHA1, oauth_timestamp=1258308730, oauth_version=1.0  Content-Length: 0 # Response containing a request token and a secret HTTP/1.1 200 OK Content-Type: application/x-www-form-urlencoded oauth_token=0e713d524f290676de8aff4073b1bb52e37f065c &oauth_token_secret=394bc633d4c93f79aa0539fd554937760f05987c 
Request to obtain a request token and secret
Response containing a request token and a secret
oauth_token in this response is a request token
that the client must use in order to get the user’s permission. The
client directs the user to visit a resource on the server to grant
# Request to obtain authorization GET /oauth/authorize?oauth_token=0e713d524f290676de8aff4073b1bb52e37f065c HTTP/1.1 Host: www.example.org
The implementation of this resource is up to the server. At this point, the server will need to check whether the user is authenticated with the server. The server may allow the user to select the parts of data that the client can access and the nature of the access. For instance, the user may grant the client permission to edit an album or create a new album but not delete any album or photos. After this step, the server directs the user back to the client. If the client has a web-based user interface, the server may redirect the user to that interface via a callback URI. If not, the server will ask the user to manually enter a verification code in the client’s user interface. With either approach, the client obtains a verification code from the server.
The client uses the verification code to obtain an access token.
The signature in this request is based on
oauth_consumer_key, the request token, the verification
# Request to obtain an access token POST /access_token HTTP/1.1  Host: www.example.org Authorization: OAuth oauth_consumer_key="a1191fd420e0164c2f9aeac32ed35d23", oauth_token="ad0d1c7a765c9e6e8b14e639c763177312d18e7e", oauth_verifier="988786765423", oauth_signature_method="RSA-SHA1", oauth_signature="698d58fd3316304181e11c6eb8127ffea7e2df46", oauth_timestamp="1258328458", oauth_nonce="109843dea839120a", oauth_version="1.0"  Content-Length: 0 HTTP/1.1 200 OK Content-Type: application/x-www-form-urlencoded oauth_token=8d743f1165c7030177040ec70f16df8bc6f415c7 &oauth_token_secret=95aec3132c167ec2df818770dfbdbd0a8b2e105e 
Request to obtain an access token and secret
Response containing an access token and token secret
This response contains an access token and a secret. The server must verify that the request token matches the consumer key before issuing an access token.
The client uses these to construct an
header with its requests to access
protected resources for that user. The signature in this
request is based on the
oauth_consumer_key, access token,
oauth_version along with any
query parameters in the URI or the body of the request when the
request media type is
# Request POST /albums/2009/08/1011/duplicate;t=a5d0e32ddff373df1b3351e53fc6ffb1 HTTP/1.1  Host: www.example.org Authorization: OAuth oauth_consumer_key="a1191fd420e0164c2f9aeac32ed35d23", oauth_token="827fa00c6f15db4063378bb988e1563e0c318dbc", oauth_signature_method="RSA-SHA1", oauth_signature="f863cceebb4f1fe60739b125128e7355dcbf14ea", oauth_timestamp="1258328889", oauth_nonce="3c93e7fdd1101e515997abf84116ef579dccce1a", oauth_version="1.0" 
Request to access a protected resource
Request containing an
Although the flow appears complex, it is designed to let clients access the user’s data without asking for the user’s credentials such as a username and password. Moreover, the user can ask the server to revoke the permission to any client.
When considering OAuth, note that the protocol is not associated with any particular resource. For a more in-depth discussion on using this protocol, see the “Beginner’s Guide to OAuth” (http://hueniverse.com/oauth).
Learn more about this topic from RESTful Web Services Cookbook.
While the REST design philosophy has captured the imagination of web and enterprise developers alike, using this approach to develop real web services is no picnic. This cookbook includes more than 100 recipes to help you take advantage of REST, HTTP, and the infrastructure of the Web. You'll learn ways to design RESTful web services for client and server applications that meet performance, scalability, reliability, and security goals, no matter what programming language and development framework you use.