Google+
Developers Network
Currently Being Moderated

OAuth for Signed REST Communication

Introduction

LivePerson supports the OAuth protocol for signing REST requests. This document describes LivePerson’s implementation of OAuth with instructions on how to use it.

Using OAuth

OAuth is an open protocol that allows secure API authorization in a simple and standard method from applications. It allows LivePerson accounts to be connected to third- party applications without the account owner having to share their password. If the account owner grants access, they can revoke access at any time by simply turning off the connection without having to change their password.

 

To create a secure application, you will require an Application Key (also known as a Consumer Key) and a Secret, as well as an Access Token and Secret. The Application Key is used to identify each application that is going to be developed. Anyone who wishes to use the LivePerson API must first receive a unique Application Key and Secret from the LivePerson Developer Community.

 

An OAuth Access Token grants an application access to a particular LivePerson account. The Access Token is specific to a single LivePerson account and Application Key, and covers the LivePerson services specified in the original request for authorization. Access Tokens are long-lived, and can be used any time the application needs to access a covered service for that account’s data. The application must have a mechanism to store Access Tokens for future use.

 

Notes:

  • LivePerson does not use a Token Exchange process. i.e., Request Tokens are not used. Developers will need to provide their own process for input of the Access Token by the account owner.
  • By default, LivePerson accounts are set to allow only Signed REST API calls.

 

 

The developer and account owner flows are presented in the following diagram.

 

flow2.gif

 

Connecting your Application with the LivePerson Account

The first time, an account owner wants to connect your application to their LivePerson account, they need to be referred to an Approval page in the LivePerson Admin Console.

 

In the LivePerson Developer Community, click the Install link in the Application keys area. An example is shown below.

 

Install_OAuth.gif

 

After logging in to their LivePerson account, the account owner will then need to grant access to their account. An example approval page is shown below.

 

Approval PageIPhone.gif

The account owner needs to approve the terms, and then click the Approve button. The following page is then displayed.

 

VerificationCode.gif

 

This page includes the Verification Code which includes the Access Token and Secret delimited by a semicolon (;). The account owner needs to copy the Verification Code and input it into the application. The application needs to provide a mechanism for the account owner to enter their LivePerson Account ID and the Verification Code. For information on creating the link to the Approval page, refer to the LivePerson Developer Community. A sample application screen is displayed next.

 

UI.gif

 

Signing OAuth Requests

You need to generate an OAuth Authorization header using the OAuth specification, Section 9.

Athorization can also be sent as a URL parameter, for more information refer to REST Overview: Requests.

 

An example output of the Authorization header is displayed next:

 

Header   Name

Authorization

Header   Value

OAuth   oauth_signature="JA0PvBbTAxmtLmzIWINpSVLshrY%3D",   oauth_version="1.0",
oauth_nonce="c1c04ec4-3125-44cf-9c39-cccb9343541b",
oauth_consumer_key="d392e7ff2e204d6c802e38fd775563d1",
oauth_signature_method="HMAC-SHA1",
oauth_token="61adad31204a4e6fab68d560f1ffb594",
oauth_timestamp="1261039670"

Note: The Authorization should be contained on a single line. Newlines have been   inserted for clarity.

 

 

The "oauth_timestamp" - The field should have the current time in UTC, represented as seconds since 1.Jan 1970.

If the value is after the current server time or if the value is before the current server time by more than 30 seconds, the request is rejected. The error message that is returned, indicates the expected time range, so the client SW can adjust its time.

 

 

 

 

An example output of Authorization as URL's query parameters is displayed next:

 

http://sales.liveperson.net/api/account/16469429/chat/availability?v=1&oauth_signature=JA0PvBbTAxmtLmzIWINpSVLshrY%3D&oauth_version=1.0&oauth_nonce=c1c04ec4-3125-44cf-9c39-cccb9343541b&oauth_consumer_key=d392e7ff2e204d6c802e38fd775563d1&oauth_signature_method=HMAC-SHA1& oauth_token=61adad31204a4e6fab68d560f1ffb594&oauth_timestamp=1261039670

 

 

Notes:

  • The LivePerson Application Key is the same as the OAuth Consumer Key.
  • LivePerson does not use the OAuth process for key exchange.
  • LivePerson currently only supports the HMAC-SHA1 signature method.


Code Sample

The sample code below shows a simple Java example for issuing a request using the Jersey OAuth client (refer to https://jersey.dev.java.net/). The example displays how to issue a GET request using the Application Key, Application Secret and Verification Code (Access Token and Access Secret).

 

Authorization as Part of Request Header

 

package common;

 

import com.sun.jersey.oauth.signature.OAuthParameters;

import com.sun.jersey.oauth.signature.OAuthSecrets;

import com.sun.jersey.oauth.client.OAuthClientFilter;

import com.sun.jersey.api.client.*;

 

import javax.ws.rs.core.MultivaluedMap;

import java.io.InputStream;

import java.io.IOException;

 

public class OAuthExample {

 

    public static void main(String[]args) {

        OAuthParameters params = new OAuthParameters();

        //baseline OAuth parameters for access to resource

        params.signatureMethod("HMAC-SHA1");

        params.consumerKey("d7af6b40fc524cf39110d86ee1bc34ab");

        params.setToken("2c9100f5a2394139840222786e9c519b");

        params.setVersion("1.0");

        params.nonce();

 

        // OAuth secrets to access resource

        OAuthSecrets secrets = new OAuthSecrets();

        secrets.consumerSecret("78536f5c93b3c170");

        secrets.setTokenSecret("2f2dcc822e5ef9fa");

 

        // Jersey client to make REST calls to token services

        Client client = Client.create();

 

        //OAuth test server resource

        WebResource resource = client.resource("http://sales.liveperson.net        /api/account/16469429/chat/availability?v=1");

 

        // if parameters and secrets remain static, filter cab be added to each web resource

        OAuthClientFilter filter = new OAuthClientFilter(client.getProviders(),   params, secrets);

 

        //filter added at the web resource level

        resource.addFilter(filter);

 

        WebResource.Builder wbr = resource.getRequestBuilder();

        try{

            ClientResponse response;

            response = wbr.get(ClientResponse.class);

 

            System.out.println("Status: " + response.getStatus());

            System.out.println("Headers: ");

            MultivaluedMap<String,String> headers = response.getHeaders();

            for(String header : headers.keySet()) {

                System.out.println(header + ": " + headers.get(header));

            }

 

            //show response's content

            int size = response.getLength();

            byte buff[] = new byte[size];

 

            InputStream is = response.getEntityInputStream();

            is.read(buff);

            String resContent = new String(buff);

            System.out.println("Content: " + resContent);

 

        } catch(UniformInterfaceException e){

            e.printStackTrace();

        } catch (IOException e) {

            e.printStackTrace();

        }

 

    }

}

 

Authorization part of Request URL Query Parameters

 

package common;

 

import com.sun.jersey.oauth.signature;

import javax.ws.rs.core.MediaType;

import java.util.*;

 

public class OAuthRequestExtImpl implements OAuthRequest{

 

  private String protocol;

  private String url;

  private String method;

  private String contentType;

 

public OAuthRequestExtImpl(String protocol, String method , String contentType, String URL ){

setProtocol(protocol);

setRequestURL (URL);

setRequestMethod(oAuthClient.getMethod());

setContentType (contentType);

}

 

public String getProtocol() {

return this.protocol;

}

 

public void setProtocol(String protocol){

this.protocol = protocol;

}

 

public String getUrl(){

return this.url;

}

 

public void setUrl(String url){

this.url = url;

}

 

public String getMethod(){

return this.method;

}

 

public void setMethod(String method){

this.method = method;

}

 

public String getContentType(){

return this.contentType;

}

 

public void setContentType(String contentType){

this.contentType = contentType;

}

 

public void addParameter(String key , String value){

parameters.put(key,value);

}

}

 

 

 

package common;

 


import com.sun.jersey.api.client.ClientHandlerException;

import com.sun.jersey.api.client.ClientRequest;

import com.sun.jersey.api.client.ClientResponse;

import com.sun.jersey.api.client.filter.ClientFilter;

 

/**

Implements default ClientFilter that will handle the OAuth request.

*/

public class OAuthClientQueryParamFilter extends ClientFilter {

 

@Override

public ClientResponse handle(ClientRequest cr) throws ClientHandlerException {

return getNext().handle(cr);

}

}

 

 

 


package common;

 

import com.sun.jersey.oauth.signature.OAuthParameters;

import com.sun.jersey.oauth.signature.OAuthSecrets;

import com.sun.jersey.oauth.client.OAuthClientFilter;

import com.sun.jersey.api.client.*;

import javax.ws.rs.core.MultivaluedMap;

import java.io.InputStream;

import java.io.IOException;

 

public class OAuthURLExample {

 

private static String createURL( String authHeader ){

    //removes the square brackets

authHeader = authHeader.substring(1, authHeader.length() - 1);


StringBuffer sb= new StringBuffer();       

//Is there "?" in the URL?       

if(getUrl().indexOf("?") <0){         

sb.append("?");       

} else{           

sb.append("&");       

}       

//remove oAuth String +1       

authHeader = authHeader.substring(6 , authHeader.length());

String[] pairs =  authHeader.split(",");

int totalPairsNum = pairs.length;

int pairNum = 1;

for(String pair : pairs){

pair = pair.trim();

String[] keyValue = pair.split("=");

String key = LPRequestValidator.dequote(keyValue[0]);

String value = LPRequestValidator.dequote(keyValue[1]);

sb.append(key);

sb.append("=");

sb.append(value);

if(pairNum < totalPairsNum)               

sb.append("&");        

pairNum++;       

}   

return getUrl() + sb.toString();

}

}


public static void main(String[]args) {


OAuthParameters params = new OAuthParameters();


 

//baseline OAuth parameters for access to resource

params.signatureMethod("HMAC-SHA1");

params.consumerKey("d7af6b40fc524cf39110d86ee1bc34ab");

params.setToken("2c9100f5a2394139840222786e9c519b");

params.setVersion("1.0");

params.nonce();


// OAuth secrets to access resource

OAuthSecrets secrets = new OAuthSecrets();

 

secrets.consumerSecret("78536f5c93b3c170");

secrets.setTokenSecret("2f2dcc822e5ef9fa");

 

String url= "http://sales.liveperson.net/api/account/16469429/chat/availability?v=1";

String contentType = "application/xml";

String method = "GET"

String protocol= "http";


// Jersey client to make REST calls to token services

Client client = Client.create(); 

 

OAuthRequestExtImpl oAuthReclienrquestExt = new OAuthRequestExtImpl(protocol, method, contentType, url);    

 

//Getting the OAuth header without initiating the request

OAuthSignature.sign(oAuthReclienrquestExt, params, secrets);


String authHeader = oAuthReclienrquestExt.getHeaderValues("Authorization").toString();

 

String url = OAuthURLExmple.createURL(authHeader);

 

ClientFilter filter = new OAuthClientQueryParamFilter();


// Jersey client to make REST calls to token services

Client client = Client.create();

Webresource resource = client.resource(url);

 

//filter added at the web resource level

resource.addFilter(filter);

 

WebResource.Builder wbr = resource.getRequestBuilder();

try{       

ClientResponse response;       

response = wbr.get(ClientResponse.class);        

System.out.println("Status: " + response.getStatus());

System.out.println("Headers: ");

MultivaluedMap headers = response.getHeaders();

for(String header : headers.keySet()) {

System.out.println(header + ": " + headers.get(header));

}

//show response's content

int size = response.getLength();

byte buff[] = new byte[size];

InputStream is = response.getEntityInputStream();

is.read(buff);

String resContent = new String(buff);

System.out.println("Content: " + resContent);

} catch(UniformInterfaceException e){

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}


 

 

For more information on using OAuth, refer to the following links:

General Information: http://oauth.net

Documentation: http://oauth.net/documentation

RFC Link: http://oauth.net/documentation/spec

Code Samples and Libraries: http://oauth.net/code

Getting Started: http://oauth.net/documentation/getting-started


Comments

Delete Document

Are you sure you want to delete this document?