Example: Java-SignPost
This example shows a three-step authentication using OAuth for a given system (represented by a consumer key and secret) and for a specific user. The identification of an user (login or registration) must be done externally using a provided callback URL. For more information refer to the OAuth documentation and SignPost
- Use a managed client connection (e. g. org.apache.http.conn.ManagedClientConnection) or a connection pool manager to reuse idle connections instead of recreating connections on each request.
- Persist the access token (consumer.getToken() and consumer.getTokenSecret()) between requests, but never save user credentials, especially an users password, on the client (e. g. smartphone). To use a system-only authentication (and to avoid user interaction), use the two-legged OAuth approach using provider.retrieveAccessToken(consumer) without providing a pin code. It is possible to wrap a whole HTTP client with an OAuthClient wrapper, thus each request can be signed automatically. Please refer to Google's implementation located on http://code.google.com/p/oauth.
- URLs for sandbox environment The named URLs in this tutorial are for the productive environment. If your work within the sandbox environment, then please use http://sandbox-immobilienscout24.de instead of http://rest.immobilienscout24.de.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
import oauth.signpost.OAuth;
import oauth.signpost.OAuthConsumer;
import oauth.signpost.OAuthProvider;
import oauth.signpost.basic.DefaultOAuthConsumer;
import oauth.signpost.basic.DefaultOAuthProvider;
/** * An example how to use OAuth with our API (based on the examples provided
* on https://github.com/kaeppler/signpost-examples).
*
* This example shows an authenticated GET request for the region completion:
*GET http(s)://rest.immobilienscout24.de/restapi/api/search/v1.0/region?q=Ber
*
* Please use the specific exceptions from SignPost in a real world application.
* Notes:
*
* To use SignPost with Android, the signpost-commonshttp4 package is
* required: http://code.google.com/p/oauth-signpost/wiki/ApacheCommonsHttp4
* It is not suggested to use java.net.URLConnection on the Android platform;
* use the HttpClient instead (you can write your own {@link http://developer.android.com/reference/org/apache/http/auth/AuthScheme.html} to * automatically sign outgoing requests).
* SignPost requires the Commons Codec package from Apache: http://commons.apache.org/codec
* More information: http://code.google.com/p/oauth-signpost/wiki/GettingStarted
*
*
*/
public final class Test {
private static final String SERVER = "http://rest.immobilienscout24.de";
private static final String OAUTH_SECURITY_PREFIX = "/restapi/security/oauth/";
private static final String AUTHORIZATION_ENDPOINT = SERVER + OAUTH_SECURITY_PREFIX + "confirm_access";
private static final String ACCESS_TOKEN_ENDPOINT = SERVER + OAUTH_SECURITY_PREFIX + "access_token";
private static final String REQUEST_TOKEN_ENDPOINT = SERVER + OAUTH_SECURITY_PREFIX + "request_token";
private static final String CONSUMER_KEY = "YOUR KEY";
// e. g. a system identifier private static final String CONSUMER_SECRET = "YOUR SECRET";
// technical and business context of the search webservice
private static final String SEARCH_PREFIX = "/restapi/api" + "/search/v1.0/";
public static void main(final String[] args) throws Exception {
final OAuthConsumer consumer = new DefaultOAuthConsumer( CONSUMER_KEY, CONSUMER_SECRET);
final OAuthProvider provider = new DefaultOAuthProvider( REQUEST_TOKEN_ENDPOINT, ACCESS_TOKEN_ENDPOINT, AUTHORIZATION_ENDPOINT);
System.out.println("Fetching request token from " + REQUEST_TOKEN_ENDPOINT); final String authUrl = provider.retrieveRequestToken(consumer, OAuth.OUT_OF_BAND);
System.out.println("Request token: " + consumer.getToken());
System.out.println("Token secret: " + consumer.getTokenSecret());
// Now we must grant the request token (out of band): use a web browser or a web view for that approach.
// After a successful login or registration (to identify an user) you can give our application the required permissions.
// Don't save the user credentials (username, password) on the client!
System.out.println( "Please visit " + authUrl + ",\nlogin or register and grant " + "this application authorization. Please copy the PIN code to " + "obtain an access token.");
System.out .println("Enter the PIN code and hit ENTER when you're done:");
final BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
final String pin = br.readLine();
br.close();
// todo: use finally to ensure to free resources
System.out.println("Fetching access token from " + ACCESS_TOKEN_ENDPOINT);
// Retrieve the access token for the given consumer granted with the
// given pin; this is required only once.
provider.retrieveAccessToken(consumer, pin);
System.out.println("Access token: " + consumer.getToken());
System.out.println("Token secret: " + consumer.getTokenSecret());
// Make an API call... it is required to sign each request (see below)
final URL url = new URL(SERVER + SEARCH_PREFIX + "region" + "?q=Ber");
HttpURLConnection request = null;
try {
request = (HttpURLConnection) url.openConnection();
consumer.sign(request);
System.out.println("Sending request to " + url);
// request.setRequestMethod("GET");
// change this for PUT, POST or
// DELETE request.connect();
System.out.println("Response: " + request.getResponseCode() + " " + request.getResponseMessage());
if (request.getResponseCode() == HttpURLConnection.HTTP_OK) {
InputStream inputStream = null; try {
inputStream = request.getInputStream();
printContent(inputStream);
}catch (IOException e) {
e.printStackTrace();
}
finally {
if (inputStream != null) {
inputStream.close();
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (request != null) {
request.disconnect();
}
}
}
/**
* Prints the received data of the given input stream to {@link System.out}
*
* @param inputStream the stream to read from
* @throws IOException if reading from the stream has failed
*/
private static void printContent(final InputStream inputStream) throws IOException {
final BufferedReader reader = new BufferedReader(new InputStreamReader( inputStream, Charset.forName("UTF-8")), 8192);
String line = "";
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
}
Doing a two-legged OAuth without user interaction using SignPost (e. g. for a system authorization using the consumer key and secret):
protected void signRequest(final HttpUriRequest request) throws OAuthException {
final OAuthConsumer consumer = new CommonsHttpOAuthConsumer("<CONSUMER_KEY>", "<CONSUMER_SECRET>");
consumer.setTokenWithSecret(null, "");// important
consumer.sign(request);
}