|
By Malla Simhachalam, with contributions from Rick Palkovic, August 2009
|
|
|
In this article, you explore an example REST application that uses the
open-source protocol OAuth to address security issues.
Contents
Web services based on REST (REpresentational State Transfer)
architecture have become popular across many enterprises, especially those
engaged in Web 2.0. REST web services are comparatively easy to develop.
They are based on standard HTTP operations such as GET, POST, PUT, and
DELETE, and their response format is free form, depending on the
application — you can use XML, JSON, or another format.
As REST web services gain in popularity, security issues become
increasingly important. You can use transport-level security (TLS/SSL)
for secure peer-to-peer authentication, but these techniques are inadequate
when requests for authentication are based on user consent or delegation
(allowing sites to authenticate on behalf of the user).
One way to address REST security issues is with the open-source protocol
OAuth. As described on the OAuth website,
OAuth is "an open protocol to allow secure API authorization in a simple
and standard method from desktop and web applications." OAuth incorporates
common principles employed by several proprietary
frameworks, including Google AuthSub, AOL OpenAuth, Yahoo BBAuth, Upcoming
API, Flickr API, and Amazon Web Services API.
The OAuth protocol enables a website or application (known as a
service consumer) to access protected resources from a web service (known as
a service provider) through an API. The API does not require users
to disclose their service provider credentials to consumers.
Not requiring users to provide their credentials directly can be a business
advantage. For example, a photo print company may need access to a
customer's private photos that have been posted to a photo hosting
service. Using the OAuth protocol, the print company can access the photos
without requiring that customers reveal their hosting service login credentials.
For use with Java technology, OAuth requires the following components:
-
Project Jersey – Project Jersey is Sun's open source
implementation of the JAX-RS
specification (JSR 311 API) for REST web services. Through extensions, Jersey
supports OAuth.
-
OpenSSO – OpenSSO, Sun's open-source implementation
of identity access management for the enterprise, supports
OAuth Token Service through extensions.
Requirements for service consumers – Consumers that use Jersey and JSR 311 API for REST web service
clients require the following components for OAuth security:
- Jersey OAuth Client Filter – Adds required security
elements automatically to outbound client requests.
- Jersey OAuth Signature Library – An API that is
used by the client filter.
Requirements for service providers – Providers of
Jersey-based REST web services require the
following components for OAuth security:
- Jersey OAuth Signature Library – API that is used
by filters and other components to validate inbound requests.
- OpenSSO OAuth Filter –
Service provider component that supplies validation for authentication and authorization.
- OpenSSO Server – Server that provides authentication and
authorization services.
- Token Service – An OpenSSO extension that issues
tokens for OAuth.
The following architecture diagram is a high-level overview of
REST-based web service consumer and provider deployment.
Figure 1. REST-Based Web Service Deployment Architecture |
The architecture is based on the OAuth component model for REST web
services. Service provider components include the web service host and
OAuth token service components. To facilitate authentication and
authorization, these components are typically either co-hosted or
co-located in the same domain.
The OAuth Client Filter intercepts outbound REST web service calls for
Jersey clients and provides security as needed. Similarly, the OpenSSO
OAuth filter intercepts inbound web service requests and validates OAuth
access tokens. OpenSSO is the user authentication and authorization
authority that exposes these interfaces not only for the browser, but for
REST web service clients through identity services. As a result, clients
can obtain user authentication and authorization through any of the
interfaces.
OAuth Token Service generates access and request tokens. It also manages
consumer secret key registrations. Currently, it is an independently
deployable web archive (war file) that uses its own repository rather than the OpenSSO
repository.
This section demonstrates REST web service security by explaining a simple
example. The example requires the software components listed below:
This article assumes that you have some familiarity with the
open-source components listed above, and that you can install and configure
them with information obtained from their download sites.
The example is a
simple Stock Quote application that was built using JAX-RS (JSR 311).
The compressed example file restsample.zip contains
the required jar files for compile, build, and deployment.
The example uses JSR 311 API and the implementation from Project Jersey.
The following instructions describe the steps to install, configure, deploy, and run
the example application.
Downloading and Installing
Begin by downloading and installing the necessary
software.
- Install and configure GlassFish v2.
Download and install GlassFish v2. The installation
is straightforward, following instructions from the GlassFish website.
This example assumes that you have installed GlassFish on localhost, port
8080. Any change in the host and port will require code changes in the example
application. GlassFish v2 requires JDK 1.6 or above as the Java environment.
- Install and configure OpenSSO.
Download and install OpenSSO.
Express build 7 is recommended.
OpenSSO is a simple
web archive (opensso.war) that you can install from the
GlassFish admin console. The installation of
OpenSSO is self-explanatory and follows the instructions available from
the
OpenSSO website.
After you have installed OpenSSO, configure it through your web browser
interface by entering the URL http://localhost:8080/opensso.
See Sun documentation for configuration instructions.
- Download and uncompress
restsample.zip, the example application.
The restsample.zip file contains the web archive
TokenService.war, an SQL script for setting up
TokenService, the Java classes and sources for StockClient and
StockService, libraries of jar files, and configuration files.
Deploying and Configuring OAuth Token Service
Next, deploy and configure the TokenService.war file.
At this writing, the OAuth Token Service uses the Java DB (Derby), and requires
several steps of configuration before it is ready to run. In the following
steps, <glassfish_directory> represents the GlassFish
installation directory, and <examples_directory> represents
the directory in which you have stored the files from restsample.zip.
-
First, ensure that the
DERBY_HOME environment variable is
set correctly by issuing the following command in a command shell:
export DERBY_HOME=<glassfish_directory>/javadb
-
Restart GlassFish and Derby with the following commands:
<glassfish_directory>/bin/asadmin stop-domain
<glassfish_directory>/bin/asadmin start-database
<glassfish_directory>/bin/asadmin start-domain
- Create the OAuth Token Service database tables using the Derby
ij utility. Before running ij for the first
time, you may need to set its executable flag. Use the following
commands. Note that ij> is the ij program
prompt, and that some command lines may appear as wrapped in this
article. Enter each command on a single line.
chmod a+x <glassfish_directory>/javadb/bin/ij
<glassfish_directory>/javadb/bin/ij
ij version 10.2
ij> connect 'jdbc:derby://localhost:1527/TokenServiceDB;create=true;user=username;password=password';
ij> run '<examples_directory>/dbsetup.sql';
ij> quit;
-
Create a JDBC connection pool and resource with the following steps.
-
In your web browser, log in to
the GlassFish
admin console with the following URL:
http://localhost:4848/
Use the default username admin and the default
password adminadmin.
-
In the GlassFish
admin console, open the Resources
entry in the list on the left, then open JDBC. Click Connection
Pools, then New.
-
Edit the text fields to read as follows:
Name: TokenServicePool
Resource Type: javax.sql.DataSource
Database Vendor: Derby
-
Click Next, then
Additional Properties. Enter the following values:
DatabaseName: TokenServiceDB
Password: password
User: username
-
Click Finish.
-
Click JDBC Resources in the left pane, then click New on the right.
Enter the following values:
JNDI Name: TokenServiceDB
Pool Name: TokenServicePool
-
Click OK.
-
Deploy the
TokenService.war file from
<examples_directory>/TokenService.war using the
GlassFish admin console.
Building and Deploying the Example Application
-
Build the
StockService web service with the following command:
cd <examples_directory>/StockService; ant
This command compiles the StockService web service and creates
a StockServiceREST.war file
in the directory <examples_directory>/StockService/dist/
-
From the GlassFish admin console, deploy the
StockServiceREST.war file.
-
Build and deploy the StockClient example.
-
Change to the StockClient directory and type the
ant command, as follows:
cd <examples_directory>/StockClient; ant
This command compiles StockClient and creates a StockClientREST.war file
in the directory <examples_directory>/StockClient/dist/.
-
In the GlassFish admin console, deploy the
StockClientREST.war file.
Running the Example Application
When you run the example application, the StockClient example code first
registers the StockClient with the TokenService by means of its Token
Secret. Consumer registration with the Token Service is done through
programmatic interfaces in the example. Consumer registration can
alternatively be done through Token Service UI interfaces, but at this
writing that approach is not mature.
The application finishes the OAuth Protocol sequence actions to obtain the
OAuth token. It uses the OAuth token to make a request to the
StockService. Upon successful validation of the OAuth Token, the StockService
responds in XML format.
Run the StockClient example with the following steps:
-
In your web browser, enter the following URL to access
the StockClient example:
http://localhost:8080/StockClientREST/
Figure 2. Running the Example Application |
-
Click GetQuote to display the user authorization page.
Figure 3. User Authorization Page |
-
Click Authorize to display the StockSample XML response message.
Figure 4. XML Response Message |
This section describes the HTTP protocol sequence data for the example
application. To view the data, you can use an HTTP protocol analyzer or
enable the GlassFish access log with protocol headers.
-
Accessing the stock client example at
http://localhost:8080/StockClientREST/
results in the following HTTP data:
GET /StockClientREST/ HTTP/1.1 200
-
Accessing the stock resource results in a 401 return and a message
indicating that the service must authorize the client:
GET /StockServiceREST/resources/stock?quote=JAVA HTTP/1.1" 401
HTTP/1.x 401 Unauthorized
X-Powered-By: Servlet/2.5Server:
Sun Java System Application Server 9.1_02WWW-Authenticate:
OAuth realm="http://www.sample.com/"
-
The stock client requests the Request Token from the OAuth Token
Service to authorize against the stock service, and obtains the oauth token:
POST /TokenService/resources/oauth/v1/get_request_token HTTP/1.1" 201 157"OAuth
oauth_signature ="%2BJfoxyJ6H5S2k4bwIZg0vaTovfI%3D",
oauth_nonce="09b10c5b-f815-4807-b92c-f6a8dcaef583",
oauth_signature_method="HMAC-SHA1",
oauth_consumer_key="http%3A%2F%2Flocalhost%3A8080%2FTokenService%2Fresources%2Foauth%2Fv1%2Fconsumer%2FStockClient",
oauth_timestamp="1247685651"
|
-
The stock client redirects to the request for user authorization with
a callback URL. In this example, it uses the default user name
demo
and password changeit).
GET /TokenService/authenticate.jsp?username=demo&password=changeit&
url=http://localhost:8080/opensso/identity&
oauth_token=http://localhost:8080/TokenService/resources/oauth/v1/rtoken/829ace0720034eb5be4c79f2e022b720&
oauth_callback=http%3A%2F%2Flocalhost%3A8080%2FStockClientREST%2FGetQuote%3Fcallback%3Dtrue%26symbol%3DJAVA
HTTP/1.1" 20
|
-
After the authentication is successful, the stock client asks for
the access token with the following request token:
POST /TokenService/resources/oauth/v1/get_access_token HTTP/1.1" 201 157
"OAuth oauth_signature="Gp4KDgza0BmsRux9CPWyGYpxU9E%3D",
oauth_nonce="6162a0e0-c734-42ee-a258-735762c3e7cd",
oauth_signature_method="HMAC-SHA1",
oauth_consumer_key="http%3A%2F%2Flocalhost%3A8080%2FTokenService%2Fresources%2Foauth%2Fv1%2Fconsumer%2FStockClient",
oauth_token="http%3A%2F%2Flocalhost%3A8080%2FTokenService%2Fresources%2Foauth%2Fv1%2Frtoken%2F829ace0720034eb5be4c79f2e022b720",
oauth_timestamp="1247685806"
|
-
The Token service issues the access token upon validation.
-
The stock client accesses the resource, this time with an authorization
header with the following access token:
GET /StockServiceREST/resources/stock?quote=JAVA HTTP/1.1" 200 308 "OAuth
oauth_signature="eJJRqklwbB1scH24CGeIyWVL0LY%3D",
oauth_nonce="124efaf3-6770-4ebe-bad2-dd28bc380210",
oauth_signature_method="HMAC-SHA1",
oauth_consumer_key="http%3A%2F%2Flocalhost%3A8080%2FTokenService%2Fresources%2Foauth%2Fv1%2Fconsumer%2FStockClient",
oauth_token="http%3A%2F%2Flocalhost%3A8080%2FTokenService%2Fresources%2Foauth%2Fv1%2Fatoken%2F0778f2002a33444d91f45a50fb3c3c77",
oauth_timestamp="1247685806"
|
-
Upon successful validation of the access token, the stock service
renders the request.
In this article, you explored an example REST application that used the
open-source protocol OAuth to address security issues. The OAuth protocol
enables a service consumer to access protected resources from a web service
provider through an API. The API gives service consumers access to services
without requiring that users disclose their service provider credentials.
-
GlassFish Application Server
-
OpenSSO
- Jersey – the JAX-RS reference implementation
- OAuth – home page
- JDK 6 – Java SE Downloads
-
Representational State Transfer (REST)
Do you have comments about this article? We welcome your participation in our community. Please keep your comments civil and on point. You may optionally provide your email address to be notified of replies - your information is not used for any other purpose. By submitting a comment, you agree to these Terms of Use.
|
Malla Simhachalam
is a member of the Access
Manager engineering team. He joined Sun in 2000 and focuses on
building identity management and identity Web services. Before
joining Sun, Malla developed Web single sign-on and real-time
systems solutions for CMC India's R&D Center. He holds an M.S.
degree from the Indian Institute of Technology, Delhi.
|
Rick Palkovic is a staff writer for Sun Developer Network. He has written about the Solaris OS
and Java technologies for longer than he likes to admit, composing everything
from man pages to technical white papers.
|
|