title: C# Web Api Facebook token based authentication
body: <p>I am trying to add Facebook authentication to a C# web api project with default web api template that's supposed to work with a separate Javascript web interface (with React).
  However, I am running into a problem of being unable to pass the authorization token from the back-end to front-end. Is there any proper way to do it? </p>
  
  <p>**</p>
  
  <h2><strong>Detailed description of what I've managed to achieve so far:</strong></h2>
  
  <p>**</p>
  
  <p>Front-end port is 3000, and back-end port is 44378.</p>
  
  <p>The sequence I'm using is the following:</p>
  
  <p>1) First, get all available login providers</p>
  
  <pre><code>GET /api/Account/ExternalLogins?returnUrl=%2F&amp;generateState=true
  </code></pre>
  
  <p>2) Then, use the Url associated with Facebook provider</p>
  
  <pre><code>/api/Account/ExternalLogin?provider=Facebook&amp;response_type=token&amp;redirect_uri=https%3A%2F%2Flocalhost%3A44378%2F&amp;state=KXiWds49DMtXLqwrPFsfvus6VfJRh4Gr5dQFq5Q10nE1
  </code></pre>
  
  <p>From this, we get several redirects to Facebook and back to local back-end like so: </p>
  
  <p><img src="https://i.imgur.com/t0nfYOP.png" alt="redirect list"></p>
  
  <p>After this, the address looks like this:</p>
  
  <pre><code>https://localhost:44378/#access_token=[...]&amp;token_type=bearer&amp;expires_in=1209600&amp;state=qrnh0GIG8ZTWTGh4e603gWLaE7E3GBUK-7dLURg6vus1
  </code></pre>
  
  <p>As far as I can tell, it's a local access token that has no direct connection with Facebook.</p>
  
  <p>3) And this is where I hit the dead end. The redirect URL is on the back-end side, so the front-end cannot gain access to this token. If I manually copypaste the token as <strong>Authorization: Bearer </strong> into the request header, I can access Web Api, but it's not passed back to the front-end component so I'm getting stuck there.</p>
  
  <p>A thing to note is that after all the redirects the back-end sets the cookie depending on whether the user has a local account: <em>.AspNet.ExternalCookie</em> if he doesn't, and <em>.AspNet.Cookies</em> if he does, but I haven't been able to find any use for them.</p>
  
  <p><strong>So the question is: is there any way to pass the local access token to the front-end component?</strong></p>
  
  <p>For the sake of completeness, here are some relevant code parts:</p>
  
  <p><em>Startup.Auth.cs</em></p>
  
  <pre><code>using System;
  using Microsoft.AspNet.Identity;
  using Microsoft.Owin;
  using Microsoft.Owin.Security.Cookies;
  using Microsoft.Owin.Security.Facebook;
  using Microsoft.Owin.Security.OAuth;
  using Owin;
  using WebApplication4.Providers;
  using WebApplication4.Models;
  
  namespace WebApplication4
  {
      public partial class Startup
      {
          public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
  
          public static string PublicClientId { get; private set; }
  
          public void ConfigureAuth(IAppBuilder app)
          {
              app.CreatePerOwinContext(ApplicationDbContext.Create);
              app.CreatePerOwinContext&lt;ApplicationUserManager&gt;(ApplicationUserManager.Create);
  
              app.UseCookieAuthentication(new CookieAuthenticationOptions());
              app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
  
              // Configure the application for OAuth based flow
              PublicClientId = "self";
              OAuthOptions = new OAuthAuthorizationServerOptions
              {
                  TokenEndpointPath = new PathString("/Token"),
                  Provider = new ApplicationOAuthProvider(PublicClientId),
                  AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
                  AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
                  // In production mode set AllowInsecureHttp = false
                  AllowInsecureHttp = true
              };
  
              var facebookOptions = new FacebookAuthenticationOptions()
              {
                  AppId = "*",
                  AppSecret = "*", //codes hidden
              };
  
              app.UseFacebookAuthentication(facebookOptions);
          }
      }
  }
  </code></pre>
  
  <p><em>AccountController.cs - just ExternalLogin method</em></p>
  
  <pre><code>[OverrideAuthentication]
  [HostAuthentication(DefaultAuthenticationTypes.ExternalCookie)]
  [AllowAnonymous]
  [Route("ExternalLogin", Name = "ExternalLogin")]
  public async Task&lt;IHttpActionResult&gt; GetExternalLogin(string provider, string error = null)
  {
      if (error != null)
      {
          return Redirect(Url.Content("~/") + "#error=" + Uri.EscapeDataString(error));
      }
  
      if (!User.Identity.IsAuthenticated)
      {
          return new ChallengeResult(provider, this);
      }
  
      ExternalLoginData externalLogin = ExternalLoginData.FromIdentity(User.Identity as ClaimsIdentity);
  
      if (externalLogin == null)
      {
          return InternalServerError();
      }
  
      if (externalLogin.LoginProvider != provider)
      {
          Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
          return new ChallengeResult(provider, this);
      }
  
      ApplicationUser user = await UserManager.FindAsync(new UserLoginInfo(externalLogin.LoginProvider,
          externalLogin.ProviderKey));
  
      bool hasRegistered = user != null;
  
      if (hasRegistered)
      {
          Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
  
           ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(UserManager,
              OAuthDefaults.AuthenticationType);
          ClaimsIdentity cookieIdentity = await user.GenerateUserIdentityAsync(UserManager,
              CookieAuthenticationDefaults.AuthenticationType);
  
          AuthenticationProperties properties = ApplicationOAuthProvider.CreateProperties(user.UserName);
          Authentication.SignIn(properties, oAuthIdentity, cookieIdentity);
      }
      else
      {
          IEnumerable&lt;Claim&gt; claims = externalLogin.GetClaims();
          ClaimsIdentity identity = new ClaimsIdentity(claims, OAuthDefaults.AuthenticationType);
          Authentication.SignIn(identity);
      }
  
      return Ok();
  }
  </code></pre>