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

Posted

技术标签:

【中文标题】ASP.net core web api:使用 Facebook/Google OAuth 访问令牌进行身份验证【英文标题】:ASP.net core web api: Using Facebook/Google OAuth access token for authentication 【发布时间】:2017-10-05 15:02:43 【问题描述】:

几天来,我正在尝试使用 Google 和 Facebook 进行 OAuth 身份验证,以便在我的 ASP.net 核心 Web api 项目中工作。

我目前的状态是:

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

我的目标是:

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

在我的 android 和 Angular 应用程序中,我能够从 google/facebook 检索访问令牌。现在,我想使用 OAuth 隐式流程,在我的 web api 上使用给定的访问令牌对用户进行身份验证(将令牌作为不记名令牌放入标头)

我的问题是:有什么通用的方法可以轻松做到这一点吗?我不想为此使用 facebook/google SDK。

我尝试了以下方法:

使用 IdentityServer4:这样我就可以在我的 webapi 上使用 facebook/google 登录,但需要重定向到 IdentityServer4 登录页面。有什么方法可以在我的应用中点击 google/fb-Button 并登录,无需重定向到 identityServer 登录页面? 使用 google/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 教程/*** 条目,但无法根据我的需要弄清楚如何在我的情况下使用它。大多数教程仅适用于 mvc-Websites 或使用 IdentityServer4 并重定向到其登录页面。

有什么建议或解决方案吗?我错过了什么?

【问题讨论】:

对于第 3 方身份验证,我相信当页面重定向回您的应用程序(用户已通过身份验证)时,HTTP 请求应包含身份验证数据。您可以编写一个全局过滤器来拦截它。在此处查看一些详细信息:andrewlock.net/… 你解决过这个问题吗? 我找到了一个解决方案(几周前,忘记在此处更新):在 IdentityServer4 的 auth 端点上,可以使用特殊参数,立即重定向到所选身份提供者的网站,而无需前往通过identityserver的登录页面。如此处所述docs.identityserver.io/en/release/endpoints/authorize.html acr_values 中的 idp:name_of_idp 参数直接重定向到身份提供者,这正是我想要的。 你找到最终解决方案了吗? 如我之前的评论中所述,如果找到解决方案。我使用了 acr_values 中的“idp:name”字段来跳过使用 identityServer4 登录页面并直接重定向到提供者 【参考方案1】:

如果我理解正确,您已经通过您的应用从 Facebook SDK 获得了 Facebook 用户令牌。 像你一样,我找不到如何使用 ASP.NET Core 库/包来做到这一点。所以我回到了基础。 我只是用 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));

【讨论】:

难道您不应该首先针对授权提供者(联合到 facebook,)验证您使用 facebook 的应用程序秘密获得的访问令牌吗?【参考方案2】:

您必须复制此article on medium 中可用的自定义代码

在 AccountController.cs 中创建一个函数

 private async Task<ExternalLoginInfo> AuthenticationManager_GetExternalLoginInfoAsync_WithExternalBearer()

并粘贴文章中给出的代码

【讨论】:

以上是关于ASP.net core web api:使用 Facebook/Google OAuth 访问令牌进行身份验证的主要内容,如果未能解决你的问题,请参考以下文章

将文件从 ASP.NET Core Web api 发布到另一个 ASP.NET Core Web api

使用 ASP.NET Core MVC 创建 Web API

使用 ASP.NET Core MVC 创建 Web API

Asp.Net Core 1.1 消费web api

使用 ASP.NET Core MVC 创建 Web API

ASP.NET Core 实战:使用 ASP.NET Core Web API 和 Vue.js 搭建前后端分离项目