6

How would one implement a login method for Linkedin, so people can just click a button and use their Linkedin account to login, just like on Facebook or Twitter? Both use OAuth, but I found specified libraries for them which are dead simple to use. For Linkedin I only found some sample code in DotNetOpenAuth but I can't make any sense out of it.

Are there any libraries I can use to facilitate a login function for Linkedin? Or any tutorials on how to do that in ASP.NET MVC with DotNetOpenAuth 4?

Scott Lance
  • 2,239
  • 1
  • 18
  • 19
CMircea
  • 3,543
  • 2
  • 36
  • 58
  • I haven't messed with OAuth yet, not more than reading about it anyway. However, I did a quick google and found this page on linkedin: https://developer.linkedin.com/documents/quick-start-guide As far as I can tell this + DotNetOpenAuth should do the job. (I'm not writing an answer cause I feel I'm not 100% sure I'm right here, and I haven't any real world experience on the subject, yet :) ) – Onkelborg Jul 11 '12 at 17:56
  • @Onkelborg, I found that, but DNOA is kinda... complicated for OAuth and the samples are old. Worse, they are filled with WebForms code and custom data structures, which makes it much harder to understand. – CMircea Jul 11 '12 at 17:57

2 Answers2

4

Here's what looks to be a pretty solid sample

http://mrsarker.wordpress.com/2011/08/20/linkedin-rest-api-in-asp-net-mvc/

[HandleError]
public class LinkedInController : Controller
{
    public ActionResult index()
    {
        return AuthenticateToLinkedIn();
    }

    static string token_secret = "";
    public ActionResult AuthenticateToLinkedIn()
    {
        var credentials = new OAuthCredentials
        {
            CallbackUrl = "http://localhost/home/callback",
            ConsumerKey = ConfigurationManager.AppSettings["ConsumerKey"],
            ConsumerSecret = ConfigurationManager.AppSettings["ConsumerSecret"],
            Verifier = "123456",
            Type = OAuthType.RequestToken
        };

        var client = new RestClient { Authority = "https://api.linkedin.com/uas/oauth", Credentials = credentials };
        var request = new RestRequest { Path = "requestToken" };
        RestResponse response = client.Request(request);

        token = response.Content.Split('&').Where(s => s.StartsWith("oauth_token=")).Single().Split('=')[1];
        token_secret = response.Content.Split('&').Where(s => s.StartsWith("oauth_token_secret=")).Single().Split('=')[1];
        Response.Redirect("https://api.linkedin.com/uas/oauth/authorize?oauth_token=" + token);
        return null;
    }

    string token = "";
    string verifier = "";
    public ActionResult Callback()
    {
        token = Request["oauth_token"];
        verifier = Request["oauth_verifier"];
        var credentials = new OAuthCredentials
        {
            ConsumerKey = ConfigurationManager.AppSettings["ConsumerKey"],
            ConsumerSecret = ConfigurationManager.AppSettings["ConsumerSecret"],
            Token = token,
            TokenSecret = token_secret,
            Verifier = verifier,
            Type = OAuthType.AccessToken,
            ParameterHandling = OAuthParameterHandling.HttpAuthorizationHeader,
            SignatureMethod = OAuthSignatureMethod.HmacSha1,
            Version = "1.0"
        };

        var client = new RestClient { Authority = "https://api.linkedin.com/uas/oauth", Credentials = credentials, Method = WebMethod.Post };
        var request = new RestRequest { Path = "accessToken" };
        RestResponse response = client.Request(request);
        string content = response.Content;


        string accessToken = response.Content.Split('&').Where(s => s.StartsWith("oauth_token=")).Single().Split('=')[1];
        string accessTokenSecret = response.Content.Split('&').Where(s => s.StartsWith("oauth_token_secret=")).Single().Split('=')[1];

        var company = new LinkedInService(accessToken, accessTokenSecret).GetCompany(162479);            

        // Some commented call to API
        //company = new LinkedInService(accessToken, accessTokenSecret).GetCompanyByUniversalName("linkedin");
       //  var companies = new LinkedInService(accessToken, accessTokenSecret).GetCompaniesByEmailDomain("apple.com");            
       // var companies1 = new LinkedInService(accessToken, accessTokenSecret).GetCompaniesByEmailDomain("linkedin.com");           
       // var companies2= new LinkedInService(accessToken, accessTokenSecret).GetCompaniesByIdAnduniversalName("162479", "linkedin");
        //var people = new LinkedInService(accessToken, accessTokenSecret).GetPersonById("f7cp5sKscd");
        //var people = new LinkedInService(accessToken, accessTokenSecret).GetCurrentUser();

        //string url = Url.Encode("http://bd.linkedin.com/pub/rakibul-islam/37/522/653");
        //var people = new LinkedInService(accessToken, accessTokenSecret).GetPeoPleByPublicProfileUrl(url);
        //var peopleSearchresult = new LinkedInService(accessToken, accessTokenSecret).SearchPeopleByKeyWord("Princes");

        var peopleSearchresult = new LinkedInService(accessToken, accessTokenSecret).GetPeopleByFirstName("Mizan");
        String companyName = company.Name;
        return Content(companyName);            
    }
}


public class LinkedInService
{
    private const string URL_BASE = "http://api.linkedin.com/v1";
    public static string ConsumerKey { get { return ConfigurationManager.AppSettings["ConsumerKey"]; } }
    public static string ConsumerKeySecret { get { return ConfigurationManager.AppSettings["ConsumerSecret"]; } }
    public string AccessToken { get; set; }
    public string AccessTokenSecret { get; set; }

    public LinkedInService(string accessToken, string accessTokenSecret)
    {
        this.AccessToken = accessToken;
        this.AccessTokenSecret = accessTokenSecret;
    }

    private OAuthCredentials AccessCredentials
    {
        get
        {
            return new OAuthCredentials
            {
                Type = OAuthType.AccessToken,
                SignatureMethod = OAuthSignatureMethod.HmacSha1,
                ParameterHandling = OAuthParameterHandling.HttpAuthorizationHeader,
                ConsumerKey = ConsumerKey,
                ConsumerSecret = ConsumerKeySecret,
                Token = AccessToken,
                TokenSecret = AccessTokenSecret
            };
        }
    }

    #region Helper

    private RestResponse GetResponse(string path)
    {
        var client = new RestClient()
        {
            Authority = URL_BASE,
            Credentials = AccessCredentials,
            Method = WebMethod.Get
        };

        var request = new RestRequest { Path = path };

        return client.Request(request);
    }

    private T Deserialize(string xmlContent)
    {
        MemoryStream memoryStream = new MemoryStream(Encoding.ASCII.GetBytes(xmlContent));
        XmlSerializer deserializer = new XmlSerializer(typeof(T));
        return (T)deserializer.Deserialize(new StringReader(xmlContent));
    }

    #endregion

    // methods removed for brevity. check the original link for full source

}
kenwarner
  • 28,650
  • 28
  • 130
  • 173
  • Is there any way to store custom data to be returned after the call? For example I want to store the URL of the original page, to redirect the user to after the login process is finished. – CMircea Jul 11 '12 at 18:45
  • @MirceaChirea You have this line CallbackUrl = "http://localhost/home/callback", I think you just have to change that line and append some parameters – Onkelborg Jul 11 '12 at 22:46
  • @Onkelborg, *facepalm*, I never thought of that, haha! – CMircea Jul 11 '12 at 23:01
  • @Onkelborg, that doesn't work. LinkedIn cannot handle that, or OAuth can't. It doesn't like query params in the callback URL. – CMircea Jul 12 '12 at 09:59
  • @MirceaChirea Hm, there are other ways :) My tip is to use the fact that you can embedd parameters in the path, ie: public ActionResult Callback(string id) and the url will be like http://localhost/LinkedIn/Callback/MYENCODEDURL?oauth-appended-params-dont-care. Take a look at http://stackoverflow.com/a/1789179/479134 :) – Onkelborg Jul 12 '12 at 10:40
0

If you don't want to code it yourself, you can always look into a third-party solution like Janrain's RPX solution: http://developers.janrain.com/. It will give you LinkedIn sign-in plus many more.

Garrett Vlieger
  • 9,354
  • 4
  • 32
  • 44
  • I decided against adding a single point of failure to my website's login process, as well as the recurring fees. – CMircea Jul 11 '12 at 18:44