The Layer 7 OAuth Toolkit is one of the most configurable and powerful OAuth implementations available on the market. A SecureSpan Gateway with OAuth Toolkit installed can play the role of the OAuth authorization server, the OAuth client or the resource server but it can also interact with other OAuth implementations (Please see http://oauth.net/code for a list of the most popular OAuth libraries).
In this tutorial, we will walk through the steps required to use the open source project Scribe-Java to create a client application that can use OAuth 1 or OAuth 2 tokens to access protected services on a SecureSpan Gateway.
The Scribe project has built-in support for many popular services that use OAuth, such as Facebook, Twitter and Google. The classes shown in this tutorial are already built in to a fork of the master branch of Scribe available on GitHub. This tutorial describes how the classes were implemented and illustrates how they can be used.
To begin, review Scribe’s Getting Started page for the installation requirements. The requirements (as of Scribe 1.3) are Scribe-1.3.0 and the Apache commons-codec-1.6.
To use the examples below you will need access to a Layer 7 SecureSpan Gateway (minimum version 6.1.5) with the following OAuth Toolkit modules:
For demonstration purposes, a pre-configured SecureSpan Gateway is available at preview.layer7tech.com. Contact Layer 7 support to register a client application or use the default values in the examples that follow.
The OAuth Toolkit’s OAuth 1.0 and 2.0 implementations require HTTPS on most endpoints to enhance security. This enhanced security requires that the Gateway’s certificate is trusted or signed by a trusted CA. If the Gateway certificate is self-signed, Scribe will not be able to connect without explicitly adding an exception to the JRE security settings. As of June 2012 the preview.layer7tech.com site is using a self-signed certificate and will require that the certificate is added to the trust store.
All OAuth 1.0 providers need to “extend” the class “DefaultApi10a”. There are three methods that must be overridden, one for each of the OAuth 1.0 endpoints:
This example is set up to allow a user of this library to specify the connection information at runtime using a “.properties” file. If the properties file is not found then the default values are used. This allows greater flexibility and makes it easier to use this class in staging or test environments where the hostname may be different than it is in production. The next section shows the rest of the class, which handles loading the properties.
Figure 2 – Layer7Api Properties Implementation: The connection parameters are loaded at runtime. If the properties file is present the default values are overridden.
You can now use the class created in the previous section to connect to the OAuth Toolkit’s OAuth 1 server as a client. You must first register a client key and secret, using the OAuth manager page at https://<server:port>/oauth/manager.
Figure 3 - Creating an OAuth Service object for OAuth 1.0.
In order to obtain an access token to access resources on a user’s behalf, we must complete the Authorization process.
From the client’s perspective, there are three tasks that must be done to get an access token:
See the OAuth 1.0 spec for details. The following line of code obtains the request token from the OAuth server:
Figure 5 – Create an OAuth 1.0 request token.
At this point in the authorization process, the resource owner is sent to the authorization server to authenticate and grant access. Usually, this is done by sending an HTTP 301 response to the user’s browser in order to redirect the user. To get the redirection URL, another line of code is used:
Figure 6 – Get the redirection URL.
If the resource owner successfully completes the authorization and authentication process, they are returned to the client with a code called a Verifier. The client uses this code to obtain the access token:
Token accessToken = service.getAccessToken(requestToken, verifier);
Figure 7 - Use the Verifier to get the access token.
Once the access token is obtained, it can be used for subsequent requests to access resources protected by OAuth. The access token should be stored securely and it may expire after a certain amount of time. To consume a service on a SecureSpan Gateway that is protected by the “Require OAuth 1.0 Token” policy fragment requires an OAuthRequest object:
OAuthRequest request = new OAuthRequest(Verb.POST, PROTECTED_RESOURCE_URI);
Response response = request.send();
Figure 8 – Using the access token with OAuthRequest.
To use Scribe as a client that consumes resources on a Gateway protected by the OAuth Toolkit requires that we extend the DefaultApi20 class:
public class Layer7Api20 extends DefaultApi20
Figure 9 – Extend the DefaultApi20 class.
As with the OAuth 1 implementation, there are some methods that need to be overridden and we will enable configuration of the hostname through a properties file that is read if it is present. If the properties file is missing then the default server is used (in this case, preview.layer7tech.com):
Figure 10 - The Layer 7 OAuth 2 implementation uses these endpoints. Some parameters are optional and hostname is loaded at runtime.
Note that this class, as written, requires the method “loadProperties” from the OAuth 1 class above. If this class is not available, the method can be moved into this class. The loading of the hostname at runtime is accomplished with the “setHostname” method:
Figure 11 - OAuth 2 setting the connection parameters.
The following example uses the “Layer7Api20” class to play the role of the client in the OAuth 2.0 authorization process. To use this code, set up a project as outlined above. Use the OAuth Manager tool to register a client application and obtain a client key and secret.
Once your project is ready, the next step is to create the OAuth Service object using the Layer7Api20 provider, the client key, secret and callback registered earlier. The callback URL that was registered must match the “redirect_uri” parameter exactly!
// Replace these with your own api key and secret
String apiKey = "Consumer";
String apiSecret = "Secret";
OAuthService service = new ServiceBuilder()
Figure 13 - Creating the OAuthService for OAuth 2.
To make debugging easier, you can also include “.debug()” in the above. The client is supposed to begin the authorization process by redirecting the resource owner to the authorization server’s authorization endpoint. In most cases, the redirection comes from responding with HTTP 301 and the header “Location: <AUTHZ_URL>”:
System.out.println("Got the Authorization URL!");
Figure 14 – Obtain the authorization URL.
In this example, a more old-fashioned technique is used – the “have the resource owner copy and paste” technique (this is for expediency and should not be used in production):
Figure 15 - Authorizing the client and getting the Authorization code.
Once the authorization code is obtained (called a “Verifier” in Scribe, which uses OAuth 1 terminology throughout the OAuth 2 implementation) after the resource owner successfully authenticates and authorizes the client, the client can request an access token from the authorization server. This is the final step in the authorization flow for the authorization code grant type.
Figure 16 – Request an access token from the authorization server.
This token can now be used to access the user’s resources on his or her behalf. Using the token requires using the OAuthRequest and OAuthResponse classes, which in turn use java.net.HttpURLConnection for sending and receiving data. The method “signRequest” is used in Scribe with OAuth 2, even though requests are not actually signed as they are in OAuth 1:
Figure 17 - Consuming resources using OAuth 2.