使用.NET Core的Firebase身份validation(JWT)

我正在开发一个处理Firebase身份validation的简单API – 稍后将用于Android客户端。

所以在Firebase控制台中,我启用了Facebook和Google登录方法,并创建了一个示例html页面,我可以使用它来测试登录方法 – 下一个函数由按钮调用:

function loginFacebook() { var provider = new firebase.auth.FacebookAuthProvider(); var token = ""; firebase.auth().signInWithPopup(provider).then(function (result) { var token = result.credential.accessToken; var user = result.user; alert("login OK"); user.getToken().then(function (t) { token = t; loginAPI(); }); }).catch(function (error) { var errorCode = error.code; var errorMessage = error.message; alert(errorCode + " - " + errorMessage); }); } 

接下来我使用令牌并通过jQuery中的简单ajax调用将其发送到我的API:

 function loginAPI() { $.ajax({ url: "http://localhost:58041/v1/Users/", dataType: 'json', type: 'GET', beforeSend: function (xhr) { xhr.setRequestHeader("Accept", "application/json"); xhr.setRequestHeader("Content-Type", "application/json"); xhr.setRequestHeader("Authorization", "Bearer " + token); }, error: function (ex) { console.log(ex.status + " - " + ex.statusText); }, success: function (data) { console.log(data); return data; } }); } 

下一站:API后端 – 用.NET Core编写。

在Startup下我配置了JwtBearer Auth(包Microsoft.AspNetCore.Authentication.JwtBearer ):

 app.UseJwtBearerAuthentication(new JwtBearerOptions { AutomaticAuthenticate = true, IncludeErrorDetails = true, Authority = "https://securetoken.google.com/PROJECT-ID", TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidIssuer = "https://securetoken.google.com/PROJECT-ID", ValidateAudience = true, ValidAudience = "PROJECT-ID", ValidateLifetime = true, }, }); 

这是Controller代码 – 具有[Authorize]属性:

 [Authorize] [Route("v1/[controller]")] public class UsersController : Controller { private readonly ILogger _logger; private readonly UserService _userService; public UsersController(ILogger logger, UserService userService) { _logger = logger; _userService = userService; } [HttpGet] public async Task<IList> Get() { return await _userService.GetAll(); } } 

API响应是200 OK(控制器内的HttpContext.User.Identity.IsAuthenticatedtrue ),但我认为不应该。 我的问题是我不完全确定这是安全的。

这是如何检查JWT令牌的签名部分的? 我看到很多代码样本提到x509或RS256算法,它们在哪里适合? 不应该使用TokenValidationParameters类中的IssuerSigningKeyTokenDecryptionKey检查某种证书或私钥? 我错过了什么?

有关该问题的相关知识来源:

  • https://blog.markvincze.com/secure-an-asp-net-core-api-with-firebase/
  • SPA – Firebase和.Net WebApi 2身份validation
  • https://stormpath.com/blog/token-authentication-asp-net-core
  • https://jwt.io/
  • https://firebase.google.com/docs/auth/admin/verify-id-tokens

Firebase使用RSA256 非对称密钥密码系统 ,这意味着它具有公钥和私钥。 使用私钥对令牌进行签名 ,同时使用公钥validation令牌

下图说明了令牌签名的发生方式。

在此处输入图像描述

在登录和访问安全端点期间,涉及以下步骤。

  1. 当我们的应用程序启动时(后来也会定期启动), JwtBearerMiddleware调用https://securetoken.google.com/my-firebase-project/.well-known/openid-configuration ,它可以访问Google的当前公钥。 重要的是,当我们使用公钥非对称密码系统时, 公钥不会被保密 ,但它的发布很明显。
  2. 客户通过Firebase使用其凭据登录(这些是客户端自己的凭据,它们与用于签署令牌的密钥无关)。
  3. 如果登录成功,则Firebase会为客户端构建JWT令牌。 此令牌的一个关键部分是使用密钥对的私钥对其进行签名 。 与公钥相反,私钥永远不会公开,它在Google的基础架构中保密。
  4. 客户端接收JWT令牌。
  5. 客户端在我们的Api上调用安全端点,并将令牌放入Authorization标头中。 此时,管道中的JwtBearerMiddleware检查此令牌,并validation它是否有效(如果它是使用Google的私钥签名的话)。 这里要认识到的重要一点是,为了进行validation,我们的Api 不需要访问私钥 。 这样做只需要公钥。 validation后,中间件相应地填充HttpContext.UserHttpContext.User.Identity.IsAuthenticated

您可以在RSA维基百科页面上找到关于此概念的更简单的描述,并在我的博客文章中找到有关Firebase + ASP.NET的更多信息。

对于后端方面,有一个Nuget包可以帮到你:

安装包AspNetCore.Firebase.Authentication

 public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { app.UseFirebaseAuthentication("https://securetoken.google.com/MYPROJECTNAME", "MYPROJECTNAME"); } 

它执行受众,发行者,签名和有效性validation

NuGet数据包使用旧的ASP NET Core 1.x身份validation机制

身份validation已更改: https : //docs.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/identity-2x