A few weeks ago the spring greenhouse project was mentioned to me. This project shows how you can interact with services that use OAuth like Twitter, Facebook and Linkedin. Just a few days a go I noticed most of the code is now available through the spring-social project. Since we need this functionality for more and more projects I decided to create a very basic sample application to show you how it works.

If you want to use this for your project have a look at the greenhouse project of springsource. They have created some nice abstractions over multiple social websites. This blog is just to help you understand the mechanism behind it and the way it is implemented in the spring-social project.

What are we going to create?

We are going to create a sample with which you can authenticate against linkedin and print all your contacts and some data about your public profile. Linkedin uses OAuth and the sample will contain the OAuth authentication using the components as provided by the spring-social project.

Introduction to OAuth

So what is up with this OAuth. In just a few words, it is an authentication service. As an application you forward a visitor to the authentication service. The visitor authenticates itself and your application receives the result using a callback. If the result is positive, the visitor has authorized your application to act on the behalf of the visitor. That way you can use services of the provider without knowing who you are dealing with. It is also possible to store the provided authentication for future use. That is what the greenhouse application does, in this sample we ask for the authentication each new session.

There are some very good resources for learning about OAuth. So if you want to know what OAuth really is about and how it works I urge you to check the following links.

Linkedin API

Linkedin provides OAuth authentication. They have written a good manual about using linkedin OAuth for authentication and the way linkedin requires authorization to get to the users data. I especially like the image they have created to show how this process works

Let us have a look at the basic steps needed to get some data from linkedin. If they are not clear, check the code later on. I think you can follow along easily.

  • Request a api key and secret using your linkedin profile on this page: https://www.linkedin.com/secure/developer.
  • In your application, redirect user to the authentication page and provide your api key.
  • User authenticates himself on the linkedin website.
  • If not done before, user needs to authorize the application to act on behalf of him.
  • User gets redirected to your site with a request token and a verification code
  • Obtain an access token using the request token and the verification code.
  • Start interacting with linkedin using your api key and the obtained access token.

That is about it

Spring-social

What is this spring-social. It is a new project that recently published M1. It provides support to interact with multiple social websites through a consitent api. There are integrations for Linkedin, Twitter, FaceBook and TripIt. There is a blog post from Craig Walls, one of the creators, that gives more details.

Show me the code

Finally, let us have a look at the code. You can find the code through github. It is a very basic spring mvc application. The most interesting part is within the class nl.gridshore.samples.springoauth.web.ConnectController.In the next code blocks I show you the methods that handle all the different stages of getting data from linkedin. Let us start by checking if the user is already connected to linked in or not.

@RequestMapping(value = "linkedin", method = RequestMethod.GET)
public String showConnectLinkedin(WebRequest request) {
    Token accessToken = obtainAccessTokenFromSession(request);
    if (accessToken == null) {
        return "connect/linkedin_connect";
    } else {
        return "connect/linkedin_connected";
    }
}
private Token obtainAccessTokenFromSession(WebRequest request) {
    return (Token) request.getAttribute(OAUTH_ACCESS_TOKEN_ATTRIBUTE, WebRequest.SCOPE_SESSION);
}

If you are authenticated with linkedin, the access token is stored in the session. Therefore we check for availability of this token in the session to determine if we need to show the page with the redirect to linkedin or the page with the options you have to ask linkedin for information. For now we assume that the user is not authenticated yet and he pushes the button to authenticate with linkedin. The form post is received by the following method.

@RequestMapping(value = "linkedin", method = RequestMethod.POST)
public String requestConnectionLinkedin(WebRequest request) {
    Token requestToken = getOAuthService().getRequestToken();
    request.setAttribute(OAUTH_REQUEST_TOKEN_ATTRIBUTE, requestToken, WebRequest.SCOPE_SESSION);
    return "redirect:" + "https://www.linkedin.com/uas/oauth/authorize?oauth_token=" + requestToken.getToken();
}

private OAuthService getOAuthService() {
    OAuthConfig config = new OAuthConfig();
    config.setRequestTokenEndpoint("https://api.linkedin.com/uas/oauth/requestToken");
    config.setAccessTokenEndpoint("https://api.linkedin.com/uas/oauth/accessToken");
    config.setAccessTokenVerb(Verb.POST);
    config.setRequestTokenVerb(Verb.POST);
    config.setApiKey(apiKey);
    config.setApiSecret(apiSecret);
    config.setCallback(callbackUrl);

    return new OAuth10aServiceImpl(
            new HMACSha1SignatureService(),
            new TimestampServiceImpl(),
            new BaseStringExtractorImpl(),
            new HeaderExtractorImpl(),
            new TokenExtractorImpl(),
            new TokenExtractorImpl(),
            config);
}

The code shows we need to create an OAuthCOnfig object using the applications api key and secret and the callback url. Using this service you can generate a request token. This token is provided to linkedin using the redirect service. Now the user does his thing in linkedin and he should see a screen like this:

Screen shot 2010-11-04 at 10.29.11.png

If the user pushes the “ok, I’ll allow it button”, we get the request token back together with a verification number to the url as provided by the callback url. The following code shows the receiving method.

    @RequestMapping(value = "linkedin", method = RequestMethod.GET, params = "oauth_token")
    public String authorizeCallback(@RequestParam(value = "oauth_verifier", defaultValue = "verifier") String verifier,
                                    WebRequest request) {
        Token requestToken = obtainRequestTokenFromSession(request);
        Token accessToken = getOAuthService().getAccessToken(requestToken, new Verifier(verifier));
        request.setAttribute(OAUTH_ACCESS_TOKEN_ATTRIBUTE, accessToken, WebRequest.SCOPE_SESSION);
        return "redirect:linkedin";

    }

As you can see we obtain the request token from the session. Using this request token and the received verification code we obtain the access token. This access token is then used for all calls to linkedin. That is shown in the following code block to obtain all connections of the authenticated user.

@RequestMapping(value = "linkedin/connections", method = RequestMethod.GET)
public String connections(WebRequest request) {
    LinkedInTemplate template = createLinkedInTemplate(request);
    List<LinkedInProfile> connections = template.getConnections();
    request.setAttribute("connections", connections, WebRequest.SCOPE_REQUEST);
    return "connections";
}

Summary

Pretty amazing that it takes only this amount of lines of code to communicate with a service like linkedin. I like it. I personally like the abstraction as used within the greenhouse application from springsource better than doing this stuff yourself. Still it does give you some insights into the way social integration works.

Tagged on:         

15 thoughts on “Connecting to Linkedin using spring-social

  • January 25, 2013 at 11:29 am
    Permalink

    Hi,

    Well, its very old thread but I need some help if someone is following this thread.

    I download the source code from this link:
    https://github.com/SpringSource/spring-net-social-linkedin

    and in this project, I am running “Spring.MvcQuickStart” under examples directory (https://github.com/SpringSource/spring-net-social-linkedin/tree/master/examples/Spring.MvcQuickStart). It works pretty well but I dont know how to get user’s email. I need to know how can I get user’s email in the controller given at this link (https://github.com/SpringSource/spring-net-social-linkedin/blob/master/examples/Spring.MvcQuickStart/Spring.MvcQuickStart/Controllers/LinkedInController.cs)

    Thanks.

  • August 8, 2012 at 7:36 pm
    Permalink

    Great post – Thank you. One question, I am able to get my LinkedIn account connected but when I go to post a status update I get a 405 error. Here is the code:

    String messsage = “test”;
    Connection linkedInConnection = repository.findPrimaryConnection(LinkedIn.class);
    LinkedIn linkedIn = linkedInConnection.getApi();
    linkedIn.networkUpdateOperations().createNetworkUpdate(message);

    I believe I need to pass over a scope of rw_nus when establishing the connection (I read through https://developer.linkedin.com/documents/authentication). I have tried that but still no luck. Note that I am able to pass the scope parameter in for Facebook and Twitter and it seems to work fine … but I can’t seem to give my App the right permission for network / status updates. Here is my JSP:

    <form action="” method=”POST”>
    Authorize LinkedIn Connection

    Any thoughts?

  • May 6, 2011 at 1:43 am
    Permalink

    Hi Jettro,

    how do you get email address for your contact list.

    sai

  • January 4, 2011 at 8:00 pm
    Permalink

    Hi Jettro,

    This works fine, But if it always retrieves my profile. if i want it to make it more general, based on users login information, updates should change. i am looking at some thing like following example.

    http://code.google.com/p/janrain4j/

    Thanks,
    Sai

  • December 13, 2010 at 10:28 pm
    Permalink

    Sorry the script tag has been stripped, it is copied from facebook, like this line:
    script src=”http://connect.facebook.net/en_US/all.js#appId=AppId&xfbml=1″…. above the fb:login-button

  • December 13, 2010 at 10:26 pm
    Permalink

    Hi Jettro,
    In status.jsp, this button can not be displayed at all,

    Do I have to intentionally add this code above it:

    Also can you tell me how to make it running under jetty? I don’t know how to modify facebook.tld and remove document tag there.

  • November 15, 2010 at 10:35 pm
    Permalink

    never mind.
    I got it working. Best tutorial so far. Do you have any tips to include or pointers to integrate spring social into spring security?

    sai.

    • November 16, 2010 at 11:18 am
      Permalink

      I guess the OAuth integration should do the job. Check the greenhouse code, they have it working. I think they even have the option to authenticate against your facebook account.

  • November 15, 2010 at 10:28 pm
    Permalink

    Hi Jettro,

    I am getting following error.
    following is my entry in config.properties. Please help….

    linkedin.callback=http://localhost:8080/connect/linkedin URL.

    Thanks,
    Sai

    HTTP Status 404 – /connect/linkedin

    ——————————————————————————–

    type Status report

    message /connect/linkedin

    description The requested resource (/connect/linkedin) is not available.

  • November 5, 2010 at 9:39 pm
    Permalink

    Great Post, easy to follow and understand. Looking second time in Spring Social….

  • November 5, 2010 at 10:00 am
    Permalink

    I think there are a problem with source code
    Regards,

    • November 5, 2010 at 10:22 am
      Permalink

      ok, can you tell me what you think is wrong? I did notice that one of the maven artifact could not be found for some reason. Fixed that. So maybe that is what you mean. If you spot other problems, please let me know.

      • November 5, 2010 at 11:05 am
        Permalink

        I believe that Nihed means that you have a problem with the display of the source code on the page. It is full of “&quot;” and “&lt;”/”&gt;” which makes it rather troublesome to read.

        • November 5, 2010 at 11:09 am
          Permalink

          Ahh, I see it, thanks, will fix it.

Comments are closed.