in Software Development

Introducing the Yahoo and LinkedIn OAuth security providers for OWIN

In my previous blog bost I wrote about the Google+ OAuth provider which I developed for ASP.NET Identity (OWIN).  This code has since been taken over by Microsoft and will be integrated into the Katana project.  I had some extra time on my hands and set about developing OAuth providers for LinkedIn and Yahoo, as they were apparently the ones which most people requested to be added.

I am glad to announce that these providers are now ready for you to use in your own projects.  In this blog post I will explain how to use these two security providers in your own application.  If you are not familiar with ASP.NET Identity I suggest you start of by reading the article entitled Create an ASP.NET MVC 5 App with Facebook and Google OAuth2 and OpenID Sign-on on the ASP.NET website.

Installing the package via NuGet

nuget

The first step is to install the package via NuGet.  The name of the package is Owin.Security.Providers

nuget2

Registering the Yahoo provider

To use the Yahoo OAuth provider you will need to create a project on the Yahoo Developer Network.  First step is to head over to http://developer.yahoo.com/ and register as a developer.  Once you are registered as a developer you will need to register a project to obtain a consumer key and secret.

Click on your name in the top right corner and select My Projects:

owin1

You will see a list of the existing projects which you have registered (if any).  Click on the Create Project button to register a new project.

owin2

Complete the new project form.  Make sure that under Application Type your select ‘Web-based’.  Under Access Scopes select ‘This app requires access to private user data’ and be sure to select at least one of the APIs under ‘Select APIs for private user data access’.  If you do not select at least one of the APIs your will get all sort of weird errors coming back from Yahoo, so just go ahead and pick one of the APIs.

owin3

Once you are done you can click on the Create Project button.  After the project is created you will be presented with a screen which will display your Consumer Key and Consumer Secret

owin4

Head on over to the Startup class located in App_Start\Startup.Auth.cs and add the namespace:

Next register the Yahoo provider in the ConfigureAuth method:

Register the LinkedIn provider

To use the LinkedIn provider you will also need to register an application on LinkedIn.  Head on over to http://developer.linkedin.com and ensure that you are registered as a developer.  Click on your name in the top right corner and select API Keys:

owin5

You will be presented with a list of your current registered applications, if any.  Click on Add New Application.

owin6

Go ahead an complete all the required information.  Once done you will be presented with a screen which displays a summary of the new application, including the API Key and Secret Key.  Take note of those two as you will need them next when you register the LinkedIn security provider.

owin7

Once again  head on over to the Startup class located in App_Start\Startup.Auth.cs and add the namespace:

And finally register the LinkedIn provider in the ConfigureAuth method:

Conclusion

This blog post showed you how to easily add external authentication using Yahoo and LinkedIn to your application.  The repository for the providers are located at https://github.com/owin-middleware/OwinOAuthProviders, so if you experience any issues or if you want to add more providers please clone the repository and send a pull request.

  • Pablo Karira

    Hello,

    I’m trying to use your security provider to authenticate with yahoo, but I keep getting an error after I authenticate and yahoo calls back to my application. (http://XXX.YYY.ZZZ/Account/%20%20%20?error=access_denied)

    I configured the yahoo application the same way as you. Any idea what I made wrong?

    Thank you

    • http://www.beabigrockstar.com/ Jerrie Pelser

      Hi Pablo,

      I got that error before when I did not select any of the APIs when configuring the application. Make sure you select one of the APIs. If you did that then I am afraid I cannot be of any more assistance. Best would be then to reach out to the people at Yahoo for assistance.

      Jerrie

      • Pablo Karira

        I did select one of the APIs, and even all of them when I couldn’t find what was wrong. I’ll keep looking.

        Thank you :)

        • http://www.beabigrockstar.com/ Jerrie Pelser

          Sorry Pablo, I cannot be of any more help. If you do solve it please post the solution here so others may also benefit from that. Thanks :)

  • Angela Temple Rogers

    I’m trying to use this with Asp.Net MVC 5 for Yahoo authentication. I have multiple subdomains and this only seems to work with the main domain. Is there any way to get it to work for subdomains? I was able to tweak the Google OAuth to work across subdomains by checking the email address, but that doesn’t appear to work here. It works fine across my subdomains with the Facebook oauth and the Microsoft oauth. Any suggestions?

    • http://www.beabigrockstar.com/ Jerrie Pelser

      Angela, do you get some sort of error message back?

      • Angela Temple Rogers

        Searching Yahoo’s developer site they state that they do not support oauth across multiple domains, so I’m just not going to use it. The error I get when coming from a subdomain is: Response status code does not indicate success: 401 (Forbidden).

        • http://www.beabigrockstar.com/ Jerrie Pelser

          I am glad you figured it out Angela. Yeah, unfortunately some of the OAuth providers are quite strict in terms of the callback URI validation and does not allow subdomains.

  • fogfree

    Hi Jerrie,
    Thanks for this excellent work and the documentation to make it simple to get started.
    Piece of cake adding yahoo and linkedin auth to my app.
    You rule!

    • http://www.beabigrockstar.com/ Jerrie Pelser

      It is a pleasure, and thank you for the kind words :)

  • Husain Jagmag

    @jerrie I am using your provider for linkedin
    and have absolutely no issues with the login itself. However, I am
    trying to now use the accesstoken retrieved using login in order to make
    a request for some linkedin data. There is a
    LinkedInAuthenticatedContext class which has the AccessCode property
    however I am unable to figure out how to access this
    LinkedInAuthenticatedContext in my code. I tried to typecast it from
    Request.GetOwnContext but that didnt work. Any inputs would be
    appreciated.

    • http://www.beabigrockstar.com/ Jerrie Pelser

      Hi Husain, I have described how to do this in a previous blog post which you can find at http://blog.beabigrockstar.com/get-the-twitter-profile-image-using-the-asp-net-identity/. That particular blog post describes how to do it for Twitter, but the principles will be exactly the same for LinkedIn

      • Husain Jagmag

        @Jerrie – That was exactly what I was looking for. Thanks a bunch. Your posts on the asp.net identity – not to mention the owin.security.providers project have saved me a lot of time and a lot of hassle rooting around the asp.net identity code with a decompiler to get the hang of what was going on behind the scenes. Many thanks!

        • http://www.beabigrockstar.com/ Jerrie Pelser

          It is a pleasure :)

  • Husain Jagmag

    @Jerrie, is there any specific reason as to why the Scope property in LinkedInAuthenticationOptions class is private? I would have expected this to be public because as a consumer I would like to decide which particular rights to get from the 3rd party and for that I would need to specify scope, which I currently cannot do. Is there some alternative way for specifying the scope that you had in mind when making this property private?

    • http://www.beabigrockstar.com/ Jerrie Pelser

      @husainjagmag:disqus The Scope property implements the IList<string> interface, so even though the property setter is private you can still add elements to, or remove elements from the list. It is just so that users cannot set the Scope to null. You can still add elements by using Scope.Add(“my extra scope”)

      Hope it makes sense

      • Husain Jagmag

        ooh….i get it *face palm* Thanks a lot :-)

        • http://www.beabigrockstar.com/ Jerrie Pelser

          No problem. When I looked at it again to try and figure out why on earth it was private it had me stumped for a few minutes as well :)

  • PeterBobPeter

    Hey Jerrie,

    Can you split up this package in two independent ones for LinkedIn and Yahoo?

    • http://www.beabigrockstar.com/ Jerrie Pelser

      I have no plans to split up the package. Is it creating some sort of problem for you?

  • adamncsu

    Since Yahoo supports OpenID, why do we need to sign up for an API key and use OAuth? Why doesn’t it work like the Google Authentication?

    • http://www.beabigrockstar.com/ Jerrie Pelser

      This provider is based on OAuth as it provides you with an OAuth token which provides further access to the Yahoo APIs. If you want an OpenID-based provider for Yahoo you are welcome to fork the project and contribute one, it will be appreciated

    • http://www.beabigrockstar.com/ Jerrie Pelser

      Actually I replied a bit too quick. The package also contains generic OpenID providers which were contributed by Jeremie Bertrand. To use install the Nuget package and register as follows:

      app.UseOpenIDAuthentication(“http://me.yahoo.com/”, “Yahoo”);

      See the demo project at https://github.com/owin-middleware/OwinOAuthProviders/blob/master/OwinOAuthProvidersDemo/App_Start/Startup.Auth.cs

      • adamncsu

        Beautiful. Such a simple solution. I can’t believe I didn’t see the OpenID providers. Thanks so much!

  • http://davidstanley.me David Stanley

    @jerriep:disqus Thanks for the hard work on this!

    I have it integrated into my mvc project. Do you have any examples or walkthroughs on how to get the razor views set up and retrieve some data in controllers?

    • http://www.beabigrockstar.com/ Jerrie Pelser

      David, I assume you are referring to retrieving data using the Yahoo or LinkedIn APIs from the controller? If so you will need to store the token using the technique I demonstrated in this blog post: http://blog.beabigrockstar.com/get-the-twitter-profile-image-using-the-asp-net-identity/

      You can then use the OAuth token to make subsequent calls to the Yahoo or LinkedIn API. I do not have samples on how to make calls to either those APIs, but you should find plenty of samples on the internet.

      Hope it helps

      • http://davidstanley.me David Stanley

        Jerrie, thanks for pointing me to the blog post. I followed it as best I could, but I am getting hung up with how to do the linkedin versions in startup.auth.cs. Also getting lost on the DownloadTwitterProfileImage task. I see where the code stores the token claims and I added that to the externalloginconfirmation method.

        I don’t want to bother you too much on this, but really your posts are the only reference I have found relating to linkedin oauth. Do you have a project sample with linkedin that retrieves some data from the user profile? I am a fish out of water here :/

        • http://www.beabigrockstar.com/ Jerrie Pelser

          If you managed to save the OAuth token from LinkedIn then you should be fine. As far as calling the LinkedIn APIs, I am afraid you are on your own on that one as I do not have examples readily available.

          Their API is REST based so you should be able to use the normal HttpClient to make call, and just pass in the OAuth token as a parameter. You can look at the source code for the LinkedIn provider to see how I retrieve the user information. Look at the following file in GitHub: https://github.com/owin-middleware/OwinOAuthProviders/blob/master/Owin.Security.Providers/LinkedIn/LinkedInAuthenticationHandler.cs

          Look at the 6 lines of code underneath the comment “Get the LinkedIn user”

          Hope this helps :)

  • David Shapiro

    @Jerrir Hi Jerrie, I’m using your above approach for Yahoo. I’m being redirected to Yahoo, logging in, and getting a confirm page authorize my app. Once clicking the confirm button, the browser gets redirected to my site (ex: http://exampledomain.com/signin-yahoo?oauth_token=TOKEN&oauth_verifier=VERIFIER) which then returns a 302 and forwards me to an MVC5 callback action..: http://exampledomain.com/Account/ExternalLoginCallback?error=access_denied
    The problem I’m facing is that error=access_denied tagged on to the end. All other providers I’ve tried work well, but Yahoo is giving me trouble. I just tried this with another Yahoo account and was successful… perhaps it’s an issue with the yahoo account I was using?

    • http://www.beabigrockstar.com/ Jerrie Pelser

      David, it is important the you request access to the Contacts API when registering your application in Yahoo as per the attached screenshot. Did you perhaps overlook that?

      • David Shapiro

        Hi Jerrie, I assume you just mean that we should be sure to select at least one of the APIs? Seems bizarre that you would need Contacts if it’s an optional API. For the purpose of my application, I’m not interested in the user’s contact list… all we want is the user’s personal information which, I believe, should be under “Social Directory (Profiles)” (I have requested access to this).
        I tried adding Contacts (in addition to SD Profiles), but I’m still getting the same result. (error=access_denied)

        • http://www.beabigrockstar.com/ Jerrie Pelser

          David, you really just need to select at least one of the APIs. It should actually not matter which one.

          Can I ask if you could perhaps download the latest source code of the project from the GitHub repository at https://github.com/owin-middleware/OwinOAuthProviders? Enable the Yahoo provider in the sample project which is included in the source code and run in debug mode and try and isolate the error like that?

          It is not ideal but it is the best I can offer you for now, and if you can locate the error we can fix it and have other people take advantage from it as well.

          • David Shapiro

            Hi again, Jerrie. I’ve managed to locate the issue in YahooAuthenticatedContext.cs @ line 39:

            var email = (from e in user["emails"]
            where e["primary"].ToString() == “true”
            select e["handle"]).FirstOrDefault();

            For the account I’m using, user["emails"] contains

            {
            [
            {
            "handle":myfirst@email.com,
            "id":"10",
            "type":"HOME"
            },
            {
            "handle":mysecond@email.com,
            "id":"1",
            "type":"HOME"
            }
            ]
            }

            Since there’s no element that’s flagged as “primary”, calling ToString on the where clause is causing a null reference exception to be thrown and context.Identity is never populated with the result that InvokeReturnPathAsync within YahooAuthenticationHandler performs a redirect with the error=access_denied querystring I was noting.

          • http://www.beabigrockstar.com/ Jerrie Pelser

            Thanks David. It is late night already here, so I will do a bug fix tomorrow morning and push a new package to Nuget

          • David Shapiro

            No worries! Thanks for the assist and the great providers!
            Do you want me to log an issue in the GitHub repository with the above?

          • http://www.beabigrockstar.com/ Jerrie Pelser

            The fix is now available, just grab latest version from Nuget (1.4.2). Give me a shout if you have any more issues.

            Not to worry about GitHub, I created an issue, but yeah next time you can log an issue on Github, thanks. :)

          • David Shapiro

            Beauty! Thanks, Jerrie; confirmed working now!

          • http://www.beabigrockstar.com/ Jerrie Pelser

            :)

  • Shanoob Shooon

    Hi Jerrie,

    Great article and code. I have a question though, because I’m having some trouble adding my own external authentication provider using the meetup.com API. Basically, the AuthenticationHandler is expecting a “state” value in the query (which meetup.com API doesn’t use) so I’m unable to complete the authentication flow after hitting “allow” once I get to the meetup login page (handler returns null because “properties” is null after unpacking “state”, which doesn’t exist to begin with. I put the relevant section of the code as a question on stackoverflow:

    https://stackoverflow.com/questions/23254350/asp-net-mvc-5-and-oauth2-login

    Thanks!