Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.net core web api: Using Facebook/Google OAuth access token for authentication

Tags:

For serveral days now I am trying to get OAuth authentication with Google and Facebook to work within my ASP.net core web api project.

my current status is:

  • I have an ASP.net core Web Api project in which the users need to be authenticated
  • I have an angular 2 web app which should use my web api (with authentication)
  • I have an android app, which should use my web api (with authentication)

my goal is:

  • Using Google/Facebook as OAuth providers for login
  • later: adding own user accounts (probably with IdentityServer4)
  • no need to redirect to a special login website (like the IdentityServer4 solution). Just hit the facebook/google button in the app, allow access, done!

In my android and angular app I am able to retrieve the access tokens from google/facebook. Now, I want to use the OAuth implicit flow, to authenticate the user on my web api, with the given access tokens (putting the tokens into the header as bearer token)

There is my problem: is there any genric way to do this easily? I do not want to use the facebook/google SDKs for this.

I have tried following:

  • using IdentityServer4: With this I am able to login with facebook/google on my webapi, but there is need of a redirection to the IdentityServer4 login page. Is there any possible way of just hitting the google/fb-Button in my app and logging in, without redirection to the identityServer login page?
  • using the google/facebook authentication middleware (https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/): But they are not validating my sent bearer token (tried countless ways to achieve proper validation). Is this even possible to use within the web api?
  • trying to use Microsoft.AspNetCore.Authentication.JwtBearer-Middleware and putting in the necessary options for google/facebook by myself, but also not validating (aswell countless attempts)

In the last few days, I have tried so much possible solutions, that I am totally stuck and lost track of what I need to do to achieve this. At this point I have read nearly every asp.net web api oauth tutorial/stackoverflow entry but can't figure out how to use this in my case as I want. Most tutorials are just for mvc-Websites or using IdentityServer4 with the redirection to its login page.

Any suggestions or solutions? What am I missing?

like image 278
Rul3r Avatar asked May 07 '17 16:05

Rul3r


1 Answers

If I undertsand correctly, you already have your Facebook user token from Facebook SDK through your app.
Like you I couldn't find how to do it with an ASP.NET Core library / package. So I went back to basics.
I just call a endpoint of my api with the Facebook token, check it against the Facebook graph api and if fine then I register the user (if required) and return my JWT token as if the user logged through a classical username / password path.

[HttpPost]
[AllowAnonymous]
[Route("api/authentication/FacebookLogin")]
public async Task<IActionResult> FacebookLogin([FromBody] FacebookToken facebookToken)
{
    //check token
    var httpClient = new HttpClient { BaseAddress = new Uri("https://graph.facebook.com/v2.9/") };
    var response = await httpClient.GetAsync($"me?access_token={facebookToken.Token}&fields=id,name,email,first_name,last_name,age_range,birthday,gender,locale,picture");
    if (!response.IsSuccessStatusCode) return BadRequest();
    var result = await response.Content.ReadAsStringAsync();
    var facebookAccount = JsonConvert.DeserializeObject<FacebookAccount>(result);

    //register if required
    var facebookUser = _context.FacebookUsers.SingleOrDefault(x => x.Id == facebookAccount.Id);
    if (facebookUser == null)
    {
        var user = new ApplicationUser {UserName = facebookAccount.Name, Email = facebookAccount.Email};
        var result2 = await _userManager.CreateAsync(user);
        if (!result2.Succeeded) return BadRequest();
        facebookUser = new FacebookUser {Id = facebookAccount.Id, UserId = user.Id};
        _context.FacebookUsers.Add(facebookUser);
        _context.SaveChanges();
    }

    //send bearer token
    return Ok(GetToken(facebookUser.UserId));
}
like image 93
François Avatar answered Sep 22 '22 13:09

François