20 thoughts on “ASP.NET WebApi Identity System: how to login with Facebook access token

  1. indichimp

    @Velerio thanks for this post its really helpful. I have been bugged by WebAPI 2 authentication and I wanted some clarification on the same.
    In my scenario, I have a simple MVC web-app to which I have added Web API controller. I want to make my API secure but I dont know how I can obtain access_token on the client side. the /token endpoint requires that I send username and password but when my user logs in using facebook I just dont have any username and password.
    In this post here you have created a controller that logs user in locally when presented with a valid access_token but in my case the MVC boilerplate code already sign-user in or registers as needed after facebook login. But I just dont have a way to allow users to securely access my API after logging in via the MVC controller. Could you please shed some light on how this can possibly be done? Any help would be highly appreciated.

    • Hi I’m sorry but I’m not sure I understand exactly what you mean: you have a scenario where a user signs in with Facebook using an MVC controller and then you want the same user to access WebAPI endpoints, am I right?
      Have you tried to decorate your API controller with the [Authorize] attribute? Provided that in the Startup.Auth.cs file you have correctly configured the cookie machinery, I believe that the WebAPI should automatically reuse the cookie being sent.
      If you inspect the request being sent by your web app to your API contoller, do you see a cookie attached?

      • indichimp

        Yes you are right, I want the user that logged in using facebook via MVC to only have access to my webAPI.

        I indeed have [Authorize] on my web api and I have the following in my webApi Config

        config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

        Cookie based auth is prone to CSRF hence Web API 2 requires that a token be used and for an API controller that has [Authorize] access is allowed only if there is a token sent as part of get/post request. My question is how to obtain the access_token when user is logged in via facebook and there is no password authentication.

      • You seem to have somewhat confused ideas about the authentication mechanism within OWIN and Asp.Net.
        If you use the boilerplate code for MVC, when you sign in the framework gives the user back an authentication cookie that is later attached by the client to every request, so that the server can identify the requester.
        As you can see, in this mechanism there’s no access token! When you login with Facebook, an alternate flow is initiated but the result is the same, the client receives the cookie and that’s it!
        The WebAPI instead, being an API, should treat every request as a full isolated and independent request, therefore no cookie should be used.
        So, in order to secure your endpoints, a token based mechanism can be used, called Bearer authentication.
        This is all independent from Facebook.

        What you are trying to do is somewhat forcing the API to use cookie authentication system, which is not ideal but can be done I believe.
        You need to remove the lines
        config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));”
        as this tells WebAPI to not use the cookie system.

  2. indichimp

    Yeah I agree that I am a bit confused.

    >> So, in order to secure your endpoints, a token based mechanism can be used,
    >> called Bearer authentication.
    >> This is all independent from Facebook.

    I believe the bearer authentication is achieved by first posting to /token endpoint and obtaining a token correct? But to post to /token you would need username and password right? When all I am doing is just facebook auth and there is no local account what do I pass in for grant_type, username and password?

    My website has ability to comment on items, I want to allow only logged in users to comment and and associate each comment with the correct user account. If I do all of this using forms for posting comments its all good but I want to build single page app in which I use angularjs that posts the comment from UI, and this is best done with web api so my web api need to distinguish different users.

  3. No Name

    You have a NullReferenceException in your code.

    In your AccountController.cs in line 38 you access the AccessTokenFormat of your OAuthBearerOptions. The access token format of your oauth bearer options is simply the value from your oauth options, in Startup.cs line 17. But here you never set your AccessTokenFormat! Please note that the default value of this property is null. It is not a default implementation.

    • Hi, thanks for your comment.
      The documentation around the OAuthAuthorizationServerOptions.AccessTokenFormat says the following:
      “The data format used to protect the information contained in the access token. If not provided by the application the default data protection provider depends on the host server. The SystemWeb host on IIS will use ASP.NET machine key data protection, and HttpListener and other self-hosted servers will use DPAPI data protection. If a different access token provider or format is assigned, a compatible instance must be assigned to the OAuthBearerAuthenticationOptions.AccessTokenProvider or OAuthBearerAuthenticationOptions.AccessTokenFormat property of the resource server.”

      In my understanding this is just saying that in case you do not specify anything (as in the example above), the rutime defaults to the format provider offered by the host server.
      If you are having a NRE, than maybe that depends on your host server.
      Let me know.

      • Wei

        I also face the same issue here, my OAuthAuthorizationServerOptions.AccessTokenFormat is always null.
        I started a new SPA template from scratch and I set a break point in the AddExternalLogin method I also find the AccessTokenFormat is null.
        What host are you using? I’m running it on IIS Express and even I push up to Azure seems like it’s always null.
        I’ve searched around some people have the same problem but seems no one figure out the answer. I also tried to figure out what’s the default implementation for the AccessTokenFormat ISSecureDataFormat, but I couldn’t find it.
        Any insights would be appreciated. Thanks!

  4. Mike

    I was wondering if you could help me out here. I’m using your example here, but I’m consistently getting “Invalid OAuthToken” back from the Graph API call to verify the token.
    My setup right now is a WPF app talking to a Web API2 server.
    Any help you can throw my way would make me eternally grateful.

  5. Mike


    “error”: {
    “message”: “Invalid OAuth access token.”,
    “type”: “OAuthException”,
    “code”: 190

    • The problem lies in your WPF code where you retrieve the access token.
      Are you sure that the URI returned after login contains the real access token and not just another code to exchange with Facebook to obtain the real token? (to be clear I just described the facebook authentication flow for asp.net identity, where the facebook oath dialog appends a code rather than access token to the redirect_url, so that the server can exchange this code for an access token)

      • Mike

        The token I’m getting has the format of a bearer token (at least it looks like one to me)

        Here are my two methods

        private void FacebookAuth() {
        var client = new RestClient(UrlBase);

        var request = new RestRequest(“api/Account/ExternalLogins”);
        request.AddParameter(“returnUrl”, “/”);
        request.AddParameter(“generateState”, “true”);

        var response = client.Execute(request);

        JArray array = JArray.Parse(response.Content);

        string fbUrl = “”;
        foreach(var o in array) {
        JObject oauthLogin = JObject.Parse(o.ToString());

        if(oauthLogin[“Name”].Value() == “Facebook”) {
        fbUrl = oauthLogin[“Url”].Value();

        if(string.IsNullOrWhiteSpace(fbUrl)) {

        Url = UrlBase + fbUrl;

        void AuthBrowser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e) {

        if(e.Uri.Host == “localhost”) {
        var client = new RestClient(UrlBase);

        var queries = HttpUtility.ParseQueryString(“?” + e.Uri.Fragment.TrimStart(‘#’));
        var token = queries[“access_token”];

        var request = new RestRequest(“api/Account/FacebookLogin”, Method.POST);
        request.AddParameter(“token”, token, ParameterType.QueryString);

        var response = client.Execute(request);




        FacebookAuth gets called first and then when the Url property is changed, it triggers browser navigation, so we get to the login screen. Once I login, the Navigated event handler triggers since we’re no longer looking at the facebook host and I attempt to call the FacebookLogin api.

      • Mike

        Thanks for the help. I realized that I should be using the client login dialog and then pass that token on, not let the Web API handle the login to facebook

  6. Murat Savas

    Mike, can you send me a sample of how you get access_token from facebook? I am getting same error when I let webapi to handle login to facebook.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s