2

When I request from LinkedIn a request token to https://api.linkedin.com/uas/oauth/requestToken, I get the following error:

oauth_problem=signature_invalid&oauth_problem_advice=com.linkedin.security.auth.pub.LoginDeniedInvalidAuthTokenException%20while%20obtaining%20request%20token%20for%20%3APOST%26https%253A%252F%252Fapi.linkedin.com%252Fuas%252Foauth%252FrequestToken%26oauth_callback%253Doob%2526oauth_consumer_key%253DI9DvH3zT4c-sjmrQTmo_AeJOfi8v8n1ChYHYAV8A3siVLyu1qLZqPq_HiGecD0bp%2526oauth_nonce%253D2958724240022%2526oauth_signature_method%253DHMAC-SHA1%2526oauth_timestamp%253D1308562221%2526oauth_version%253D1.0%0AOAU%3AI9DvH3zT4c-sjmrQTmo_AeJOfi8v8n1ChYHYAV8A3siVLyu1qLZqPq_HiGecD0bp%7C%2A01%7C%2A01%7C%2A01%3A1308562221%3AkPisU0TwUgiNIYpigUrKITMwo7c%3D

This is a HTTP 401 Unauthorized response.

The Exception:

net.oauth.exception.OAuthException: HTTP/1.0 401 Unauthorized
oauth_problem=signature_invalid&oauth_problem_advice=com.linkedin.security.auth.pub.LoginDeniedInvalidAuthTokenException%20while%20obtaining%20request%20token%20for%20%3APOST%26https%253A%252F%252Fapi.linkedin.com%252Fuas%252Foauth%252FrequestToken%26oauth_callback%253Doob%2526oauth_consumer_key%253DI9DvH3zT4c-sjmrQTmo_AeJOfi8v8n1ChYHYAV8A3siVLyu1qLZqPq_HiGecD0bp%2526oauth_nonce%253D2958724240022%2526oauth_signature_method%253DHMAC-SHA1%2526oauth_timestamp%253D1308562221%2526oauth_version%253D1.0%0AOAU%3AI9DvH3zT4c-sjmrQTmo_AeJOfi8v8n1ChYHYAV8A3siVLyu1qLZqPq_HiGecD0bp%7C%2A01%7C%2A01%7C%2A01%3A1308562221%3AkPisU0TwUgiNIYpigUrKITMwo7c%3D
    at net.oauth.consumer.OAuth1Consumer.requestUnauthorizedToken(OAuth1Consumer.java:133)
    at com.neurologic.example.LinkedInExample.requestUnauthorizedRequestToken(LinkedInExample.java:39)
    at com.neurologic.example.LinkedInExample.main(LinkedInExample.java:57)

The example source code to connect to LinkedIn:

/**
 * 
 */
package com.neurologic.example;

import net.oauth.consumer.OAuth1Consumer;
import net.oauth.exception.OAuthException;
import net.oauth.provider.OAuth1ServiceProvider;
import net.oauth.signature.impl.OAuthHmacSha1Signature;
import net.oauth.token.v1.AccessToken;
import net.oauth.token.v1.AuthorizedToken;
import net.oauth.token.v1.RequestToken;

/**
 * @author Buhake Sindi
 * @since 14 June 2011
 *
 */
public class LinkedInExample {

    private static final String LINKEDIN_API_URL = "https://api.linkedin.com";
    private static final String API_KEY = "ENTER-API-KEY-HERE";
    private static final String API_SECRET  = "ENTER-API-SECRET-HERE";
    private static final String CALLBACK_URL = "oob";
    private OAuth1Consumer consumer;


    /**
     * 
     */
    public LinkedInExample() {
        super();
        // TODO Auto-generated constructor stub
        consumer = new OAuth1Consumer(API_KEY, API_SECRET, new OAuth1ServiceProvider(LINKEDIN_API_URL + "/uas/oauth/requestToken", LINKEDIN_API_URL + "/uas/oauth/authorize", LINKEDIN_API_URL + "/uas/oauth/accessToken"));
    }

    public RequestToken requestUnauthorizedRequestToken() throws OAuthException {
        return consumer.requestUnauthorizedToken(LINKEDIN_API_URL, CALLBACK_URL, null, new OAuthHmacSha1Signature());
    }

    public String getAuthorizationUrl(RequestToken token) throws OAuthException {
        return consumer.createOAuthUserAuthorizationUrl(token, null);
    }

    public AccessToken requestAccessToken(AuthorizedToken authorizedToken, RequestToken requestToken) throws OAuthException {
        return consumer.requestAccessToken(LINKEDIN_API_URL, requestToken, authorizedToken, new OAuthHmacSha1Signature());
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        try {
            LinkedInExample example = new LinkedInExample();
            RequestToken rt = example.requestUnauthorizedRequestToken();

            //Now that we have request token, let's authorize it....
            String url = example.getAuthorizationUrl(rt);

            //Copy the URL to your browser and make sure that OAuth 1 Servlet is running....
        } catch (OAuthException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

My library: JOAuth (version 1.2.1). What have I done wrong to return a com.linkedin.security.auth.pub.LoginDeniedInvalidAuthTokenException advice from LinkedIn?

Thanks

PS: OAuth 1 works perfectly with Twitter (tested), hence I don't understand what's going on. Also, LinkedIn uses OAuth 1.0 Revision A, which JOAuth conforms (as well as RFC5849).

Buhake Sindi
  • 87,898
  • 29
  • 167
  • 228

3 Answers3

0

It seems like the JOAuth library isn't properly calculating the signature. I would need to see the full request and response to be able to debug further. What is your application name?

Adam Trachtenberg
  • 2,231
  • 1
  • 14
  • 18
  • My Application name is "Music 4.0". Isn't LinkedIn uses `HMAC-SHA1` signature? The same signature works for Twitter. – Buhake Sindi Jun 21 '11 at 05:37
  • We also use HMAC-SHA1, but I've found a number of quirky bugs in OAuth libraries. Maybe we have a character Twitter doesn't have. – Adam Trachtenberg Jun 21 '11 at 06:35
  • Do you mind posting the bug and the problem character, etc. I will see where I go wrong. – Buhake Sindi Jun 21 '11 at 06:38
  • Hum... I can confirm your signature base string looks correct. And that you can use your keys to get a requestToken. Looking at your signature I see kPisU0TwUgiNIYpigUrKITMwo7c= and I got kKdzzmPIRsc7qy/gJ3+cw02d9NM= with my code. I took a look at the source and nothing jumped out. I'll need time tomorrow to look again. Can you try this another time and post the full request/response? – Adam Trachtenberg Jun 21 '11 at 07:03
  • @Adam Trachtenberg, The signature will always be different because of `oauth_nonce` and `oauth_timestamp`. I don't know how else I can help from here. – Buhake Sindi Jun 21 '11 at 08:33
  • I override my oauth_nonce and oauth_timestamp to match yours. :) I don't do much Java programming. Can you give me a simple way to execute this code from the command line and view the request and response? I can then do interactive debugging by comparing it to code in another language and see what's going on. – Adam Trachtenberg Jun 21 '11 at 16:21
  • Sure, just take the full source code implemented on this post, find a decent `log4j.properties` from the web and add it to the root folder of the app. Then type `java LinkedInExample -cp joauth-1.2.1.jar`. – Buhake Sindi Jun 21 '11 at 21:07
  • I got it running in Eclipse after downloading a bunch of JARs. The good news is I can reproduce the error. The bad news is that I haven't had time to debug further. Is there an easy way to print the entire HTTP exchange, get the signature base string, etc. – Adam Trachtenberg Jun 22 '11 at 05:14
  • Yes, you can just place the code found [here](http://www.benmccann.com/dev-blog/sample-log4j-properties-file/) into a `log4j.properties` in a `src` folder in Eclipse. If you want to configure the log4J properties file, see explanation [here](http://publib.boulder.ibm.com/infocenter/p8docs/v4r5m1/index.jsp?topic=%2Fcom.ibm.p8.doc%2Frm_help%2Fadmin%2Fconfigure_rm_logging.htm). Google Apache Log4J to download the latest Log4J jars. – Buhake Sindi Jun 22 '11 at 05:24
  • Thanks. I've been super busy, so I am lagging on debugging this. I hope to find time tomorrow... – Adam Trachtenberg Jun 23 '11 at 05:14
  • I've just tested this code with Yahoo OAuth and it worked like a charm. There's something on LinkedIn I don't see. – Buhake Sindi Jul 07 '11 at 06:03
0

Please refer to my answer to Absolute minimum code to get a valid oauth_signature populated in Java or Groovy? Maybe it will help :)

Community
  • 1
  • 1
DeepNightTwo
  • 4,809
  • 8
  • 46
  • 60
  • I'm the author of JOAuth & I tell you it works for Twitter (OAuth 1) as well as Facebook (OAuth 2). My problem is that it doesn't get a request token from LinkedIn particularly. – Buhake Sindi Jun 23 '11 at 19:58
0

I've figured it out. The problem was with normalizing the Base String URI. The path of the URI must not be in lowercase (in which mine did). I've fixed the issue. The issue was in method found in net.oauth.util.OAuth1Util.normalizeUrl() method.

Buhake Sindi
  • 87,898
  • 29
  • 167
  • 228