Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
Developer
behrk2
Posts: 367
Registered: ‎11-25-2009
My Device: Not Specified
Accepted Solution

OAuth / OAuth workaround?

Hi everyone, I have searched the Java Development forum for any topics related to OAuth - Unfortunately, I wasn't suprised when I found hardly anything. I am trying to develop an application for BlackBerry devices to, using the OAuth protocol, connect to Netflix. I have not found any OAuth libraries that are compatible with BlackBerry.

 

The only one I have found is this J2ME OAuth Library...http://github.com/fireeagle/j2me-oauth

 

...I have yet to look into it in great detail.

 

Anyways, my question is (assuming there are no other libraries), what is a work around for this? Would it be possible to have my application use an embedded browser, and do the authentication via javascript or php or something like that, and then find a way to pass the authenticated token to my application? I want my app to be a native Java application on the BlackBerry, I don't want it to turn into a complete web application that just displays in an embedded browser. Any thoughts?

Developer
klerisson
Posts: 78
Registered: ‎12-03-2009
My Device: Not Specified

Re: OAuth / OAuth workaround?

Hey behrk2!

 

It's possible, I had done an integration with twitter.com using OAuth authentication. You just have to read and follow the OAuth specification. Did you still facing some problems? Which of then?

--
Feel free to press the kudos button on the left side to thank the user that helped you.
Please mark posts as solved if you found a solution.
Developer
behrk2
Posts: 367
Registered: ‎11-25-2009
My Device: Not Specified

Re: OAuth / OAuth workaround?

[ Edited ]

Thanks for your reply, klerisson!

 

I was actually able to develop a working example using the OAuth java library, however I am unsure how I can get those classes and dependencies working on the BlackBerry. I can post the code that I have, if you are interested in seeing it.

 

When I got it working (as a Java application) and tried to then run it in the BlackBerry simulator, I would receive a JVM 104 Runtime Exception, because "Module 'core-20081022' not found".

 

I have been experimenting with signpost since then (as I hear it will work on BlackBerry - not sure, though), but I am receiving authentication errors from the Netflix server.

 

Any help you could provide would be greatly appreciated. I have been at this for weeks now...

 

Thanks!

 

 

Developer
klerisson
Posts: 78
Registered: ‎12-03-2009
My Device: Not Specified

Re: OAuth / OAuth workaround?

[ Edited ]

Sorry to be late, but here we come!

Firt of all, take a look at this big picture: http://3.bp.blogspot.com/_WaWcMRB-faw/SdZ3vyqDcLI/AAAAAAAAAcw/k6KmBLnOXTg/s1600-h/TwitterOAuthFlow.j...

It sumarizes the OAuth process flow.

As you can see the first step is to build the parameters:

 

oauth_timestamp:

 

static long timestamp() {
return new Date().getTime()/1000;
}


oauth_nonce:

 

private static String nonce() {
return Long.toString(Math.abs(RandomSource.getLong()));
}

 

oauth_signature_method and oauth_version you have to find at the third party documentation. At Twitter, for instance, the accept HMAC-SHA1 as signature method and the version is 1.0.

The oauth_consumer_key you have to ask the third party.

And then, the second step is to request the token:

public static String requestToken(){
String url = Const.REQUEST_TOKEN_URL;
String header = oauth_header(url, HttpProtocolConstants.HTTP_METHOD_GET);
String requestTokenUrl = concatURL(url, header);
HttpConnection httpConn = null;
InputStream input = null;
try{
HttpConnectionFactory factory = new HttpConnectionFactory( requestTokenUrl,
HttpConnectionFactory.TRANSPORT_WIFI |
HttpConnectionFactory.TRANSPORT_WAP2 |
HttpConnectionFactory.TRANSPORT_BIS |
HttpConnectionFactory.TRANSPORT_BES |
HttpConnectionFactory.TRANSPORT_DIRECT_TCP);
httpConn = factory.getNextConnection();
httpConn.setRequestMethod(HttpProtocolConstants.HTTP_METHOD_GET);
httpConn.setRequestProperty("WWW-Authenticate","OAuth realm=http://twitter.com/");
httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

input = httpConn.openDataInputStream();
int resp = httpConn.getResponseCode();
if (resp == HttpConnection.HTTP_OK) {
StringBuffer buffer = new StringBuffer();
int ch;
while ( (ch = input.read()) != -1){
buffer.append( (char) ch);
}
String content = buffer.toString();
Const.token = content.substring(content.indexOf((Const.OAUTH_TOKEN+"="))+(Const.OAUTH_TOKEN+"=").length(), content.indexOf('&'));
Const.tokenSecret = content.substring(content.indexOf((Const.OAUTH_TOKEN_SECRET+"="))+(Const.OAUTH_TOKEN_SECRET+"=").length(), content.length());

}
return (getTwitterMessage(httpConn.getResponseCode()));
} catch (IOException e) {
return "exception";
} catch (NoMoreTransportsException nc) {
return "noConnection";
} finally {
try {
httpConn.close();
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

 

You will need to build the http header and the signature:

 

 

public static String oauth_header(String url, String method) {
String nonce = nonce();
long timestamp = timestamp();
Hashtable pairs = new Hashtable();

pairs.put(Const.OAUTH_CONSUMER_KEY, Const.consumerKey);
pairs.put(Const.OAUTH_NONCE, nonce);
pairs.put(Const.OAUTH_SIGNATURE_METHOD, Const.SIGNATURE_METHOD);
pairs.put(Const.OAUTH_TIMESTAMP, Long.toString(timestamp));
if(Const.token != null) {
pairs.put(Const.OAUTH_TOKEN, Const.token);
//pairs.put(OAUTH_VERIFIER, verifier);
}
pairs.put(Const.OAUTH_VERSION, "1.0");

String sig = signature(method, url, pairs);
//pairs.put(Const.OAUTH_SIGNATURE, escape(sig));

StringBuffer header_sb = new StringBuffer();
if(method.equals("GET"))
{
header_sb.append(Const.OAUTH_CONSUMER_KEY).append("=").append(URLUTF8Encoder.encode(Const.consumerKey)).append(",");
header_sb.append(Const.OAUTH_NONCE).append("=").append(nonce).append(",");
header_sb.append(Const.OAUTH_SIGNATURE).append("=").append(URLUTF8Encoder.encode(sig)).append(",");
header_sb.append(Const.OAUTH_SIGNATURE_METHOD).append("=").append(URLUTF8Encoder.encode(Const.SIGNATURE_METHOD)).append(",");
header_sb.append(Const.OAUTH_TIMESTAMP).append("=").append(Long.toString(timestamp)).append(",");
if(Const.token != null) {
header_sb.append(Const.OAUTH_TOKEN).append("=").append(URLUTF8Encoder.encode(Const.token)).append(",");
}
header_sb.append(Const.OAUTH_VERSION).append("=").append("1.0");
}
else if(method.equals("POST"))
{
header_sb.append(Const.OAUTH_CONSUMER_KEY).append("=").append(URLUTF8Encoder.encode(Const.consumerKey)).append("&");
header_sb.append(Const.OAUTH_NONCE).append("=").append(nonce).append("&");
header_sb.append(Const.OAUTH_SIGNATURE).append("=").append(URLUTF8Encoder.encode(sig)).append("&");
header_sb.append(Const.OAUTH_SIGNATURE_METHOD).append("=").append(URLUTF8Encoder.encode(Const.SIGNATURE_METHOD)).append("&");
header_sb.append(Const.OAUTH_TIMESTAMP).append("=").append(Long.toString(timestamp)).append("&");
if(Const.token != null) {
header_sb.append(Const.OAUTH_TOKEN).append("=").append(URLUTF8Encoder.encode(Const.token)).append("&");
//header_sb.append(OAUTH_VERIFIER).append("=").append(escape(verifier)).append("&");
}
header_sb.append(Const.OAUTH_VERSION).append("=").append("1.0");
}
return header_sb.toString();
}

private static String signature(String method, String requestURL, Hashtable pairs) {
StringBuffer sb = new StringBuffer();
String[] keys = new String[pairs.size()];
Enumeration e = pairs.keys();
int i = 0;

while(e.hasMoreElements()) {
String k = (String)e.nextElement();
keys[i++] = k + "=" + URLUTF8Encoder.encode((String)pairs.get(k));
}
Arrays.sort(keys, new Comparator() {
public int compare(Object arg0, Object arg1) {
return ((String)arg0).compareTo((String)arg1);
}
});
for(i = 0; i < keys.length; i++) {
sb.append(keys[i]).append('&');
}
sb.deleteCharAt(sb.length()-1);
String msg = method.toUpperCase() +"&" + URLUTF8Encoder.encode(requestURL) + "&" + URLUTF8Encoder.encode(sb.toString());
System.out.println(msg);

StringBuffer key = new StringBuffer();
if(Const.consumerSecret != null) key.append(URLUTF8Encoder.encode(Const.consumerSecret));
key.append('&');

if(Const.tokenSecret != null){
key.append(URLUTF8Encoder.encode(Const.tokenSecret));
}

try {
return hmacsha1(key.toString(), msg);
} catch (Exception ex) {
return null;
}
}

private static String hmacsha1(String key, String message)
throws CryptoTokenException, CryptoUnsupportedOperationException, IOException {
HMACKey k = new HMACKey(key.getBytes());
HMAC hmac = new HMAC(k, new SHA1Digest());
hmac.update(message.getBytes());
byte[] mac = hmac.getMAC();
return Base64OutputStream.encodeAsString(mac, 0, mac.length, false, false);
}

 

 

After that you have to redirect the user to authorize the token. Just open the browser (or implement your own browser field) for the user enter his username and password.

The last step is to exchange the token or in others words to request the access token:

 

public static String accessToken(){
OutputStream os = null;
InputStream input = null;
HttpConnection httpConn = null;
String url = Const.ACCESS_TOKEN_URL;
String header = oauth_header(url, HttpProtocolConstants.HTTP_METHOD_POST);

try{
HttpConnectionFactory factory = new HttpConnectionFactory( url,
HttpConnectionFactory.TRANSPORT_WIFI |
HttpConnectionFactory.TRANSPORT_WAP2 |
HttpConnectionFactory.TRANSPORT_BIS |
HttpConnectionFactory.TRANSPORT_BES |
HttpConnectionFactory.TRANSPORT_DIRECT_TCP);
httpConn = factory.getNextConnection();

httpConn.setRequestMethod(HttpProtocolConstants.HTTP_METHOD_POST);
httpConn.setRequestProperty("WWW-Authenticate","OAuth realm=http://twitter.com/");
httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
httpConn.setRequestProperty("Content-Length", Integer.toString(header.getBytes().length));
os = httpConn.openOutputStream();
os.write(header.getBytes());
//os.flush();
os.close();
os = null;

input = httpConn.openDataInputStream();
int resp = httpConn.getResponseCode();
if (resp == HttpConnection.HTTP_OK) {
StringBuffer buffer = new StringBuffer();
int ch;
while ( (ch = input.read())!= -1){
buffer.append( (char) ch);
}
String content = buffer.toString();

String[] token = new String[2];
Const.token = token[0] = content.substring(content.indexOf((Const.OAUTH_TOKEN+"="))+(Const.OAUTH_TOKEN+"=").length(), content.indexOf('&'));
Const.tokenSecret = token[1] = content.substring(content.indexOf((Const.OAUTH_TOKEN_SECRET+"="))+(Const.OAUTH_TOKEN_SECRET+"=").length(), content.indexOf("&user"));

PreferencesStore ps = new PreferencesStore();
ps.setToken(token);
}
return (getTwitterMessage(httpConn.getResponseCode()));
} catch (IOException e) {
return "exception";
} catch (NoMoreTransportsException nc) {
return "noConnection";
} finally {
try {
httpConn.close();
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

 

 

That's all!

This code is not optimized, sorry! But as you can see to deal with OAuth is not complicated, it's rely on http requests.
At this page you can check if your signature and OAuth header are correct according to the OAuth specification.
Any question I will be glad to help you!

 

 

 

 

--
Feel free to press the kudos button on the left side to thank the user that helped you.
Please mark posts as solved if you found a solution.
Developer
sivalingaraja
Posts: 157
Registered: ‎07-09-2009
My Device: Not Specified

Re: OAuth / OAuth workaround?

Hello klerisson,

 

I need to use oauth for twitter like websites in my application.

 

Can you send me the library and sample code for oauth?

 

Thanks in advance,

 

Sivalingaraja

Developer
klerisson
Posts: 78
Registered: ‎12-03-2009
My Device: Not Specified

Re: OAuth / OAuth workaround?

Hey Sivalingaraja!

Sorry for the late answer, but I was on vocation :smileywink:

 

Anyway, as I had post above I did not use any library for OAuth/Twitter. I just follow the OAuth specification and the Twitter API. All the code that I used is above.

 

In case of any problem just let me know.

See you!

--
Feel free to press the kudos button on the left side to thank the user that helped you.
Please mark posts as solved if you found a solution.
Developer
zany
Posts: 222
Registered: ‎11-11-2009
My Device: Storm

Re: OAuth / OAuth workaround?

[ Edited ]

Hi Sivalingaraja,

      I am also working on OAuth process. For which i got code from the following link, which is really for me, hopefully will be useful for. Which having ready code to get the request token, access token and to make resource request.

     Which will be really useful for you:smileyhappy:

 

   http://github.com/greyson/j2me-oauth

with regards,
Vignesh J

-------------------------------------------------------------------------------------------------------------------------------------------------------------------
Don't forget to mark your post as solved if you get the answer and dont forget to give kudos if the answer is useful for you.
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
Developer
behrk2
Posts: 367
Registered: ‎11-25-2009
My Device: Not Specified

Re: OAuth / OAuth workaround?

Vingesh,

 

Have you gotten the j2me-oauth code to work? Thanks.

 

-Kevin

Developer
behrk2
Posts: 367
Registered: ‎11-25-2009
My Device: Not Specified

Re: OAuth / OAuth workaround?

[ Edited ]

Hi klerrison,

 

I'm still trying to implement what you have provided, but I am running into difficulties. I was wondering if I could see your Const class? Also, I'm wondering what your getTwitterMessage(), PreferencesStore(), and concatUrl() methods do...

 

Thanks,

 

Kevin

Developer
zany
Posts: 222
Registered: ‎11-11-2009
My Device: Storm

Re: OAuth / OAuth workaround?

Hi Kevin,

     Ya, it is working fine for me with one or 2 small changes based on our thinking logic. With that code, i was about to complete my app. It was really useful.

with regards,
Vignesh J

-------------------------------------------------------------------------------------------------------------------------------------------------------------------
Don't forget to mark your post as solved if you get the answer and dont forget to give kudos if the answer is useful for you.
-------------------------------------------------------------------------------------------------------------------------------------------------------------------