ASP.net核心web api:使用Facebook/Google OAuth访问令牌进行身份验证

Rul*_*l3r 17 c# authentication google-oauth asp.net-core-webapi angular

几天来,我正试图通过Google和Facebook获得OAuth身份验证,以便在我的ASP.net核心web api项目中工作.

我现在的状态是:

  • 我有一个ASP.net核心Web Api项目,用户需要在其中进行身份验证
  • 我有一个有角度的2 web应用程序,它应该使用我的web api(带身份验证)
  • 我有一个Android应用程序,它应该使用我的web api(带身份验证)

我的目标是:

  • 使用Google/Facebook作为OAuth提供商进行登录
  • 稍后:添加自己的用户帐户(可能使用IdentityServer4)
  • 无需重定向到特殊的登录网站(如IdentityServer4解决方案).只需点击应用中的facebook/google按钮,即可访问,完成!

在我的Android和角度应用程序中,我能够从谷歌/ Facebook检索访问令牌.现在,我想使用OAuth隐式流,使用给定的访问令牌对我的web api上的用户进行身份验证(将令牌作为承载令牌放入标头中)

有我的问题:有没有任何genric方式来轻松做到这一点?我不想使用facebook/google SDK.

我试过以下:

  • 使用IdentityServer4:有了这个,我可以在我的webapi上使用facebook/google登录,但是需要重定向到IdentityServer4登录页面.有没有办法在我的应用程序中点击google/fb-Button并登录,而无需重定向到identityServer登录页面?
  • 使用谷歌/ Facebook验证的中间件(https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/):但是他们没有验证我发送承载令牌(试过无数种方法来实现适当的验证).这甚至可以在web api中使用吗?
  • 试图使用Microsoft.AspNetCore.Authentication.JwtBearer-Middleware并自己为google/facebook添加必要的选项,但也没有验证(以及无数次尝试)

在过去的几天里,我已经尝试了很多可能的解决方案,我完全陷入困境并且忘记了为实现这一目标我需要做些什么.在这一点上,我已经阅读了几乎每个asp.net web api oauth教程/ stackoverflow条目,但无法弄清楚如何在我的情况下使用这个我想要的.大多数教程仅适用于mvc-Websites或使用IdentityServer4重定向到其登录页面.

任何建议或解决方案?我错过了什么?

Fra*_*ois 15

如果我忘记了,你已经通过你的应用程序从Facebook SDK获得了你的Facebook用户令牌.
像你一样,我找不到如何使用ASP.NET核心库/包.所以我回到了基础.
我只是使用Facebook令牌调用我的api的端点,将其与Facebook图形api一起检查,如果没问题,那么我注册用户(如果需要)并返回我的JWT令牌,就好像用户登录了经典的用户名/密码路径一样.

[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));
}
Run Code Online (Sandbox Code Playgroud)