【问题标题】:Firebase Authentication (JWT) with .NET Core使用 .NET Core 的 Firebase 身份验证 (JWT)
【发布时间】:2017-07-09 06:47:33
【问题描述】:

我正在开发一个简单的 API,用于处理 Firebase 进行的身份验证 - 稍后将用于 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,
    },
});

这是控制器代码 - 带有[Authorize] 属性:

[Authorize]
[Route("v1/[controller]")]
public class UsersController : Controller
{
    private readonly ILogger _logger;
    private readonly UserService _userService;

    public UsersController(ILogger<UsersController> logger, UserService userService)
    {
        _logger = logger;
        _userService = userService;
    }

    [HttpGet]
    public async Task<IList<User>> Get()
    {
        return await _userService.GetAll();
    }
}

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

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

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

【问题讨论】:

  • 即使不传递Authorization 标头,响应也是200 OK?那肯定是错的。在app.UseJwtBearerAuthentication() 之前或之后有app.UseMvc() 电话吗?
  • 如果我没有传递Authorization 标头,则响应为401app.UseMvc()app.UseJwtBearerAuthentication() 之后。我只是不确定安全性。我试图破解我的应用程序但无法破解。也许我只是偏执。
  • 嗯,但你说响应“不应该是 200”。为什么?您是否故意在标头中传递了不正确的标记?或者你为什么期望响应不是 200?
  • 由于我没有在我的代码中的任何地方提供私钥,所以我认为这应该行不通,但是在无法破解它之后,我认为我只是偏执。
  • 恐怕您误解了令牌签名在此流程中的工作原理。您的应用程序不应提供(或拥有)私钥(或任何类型的密钥)。我在我的博文中添加了对流程的描述:blog.markvincze.com/secure-an-asp-net-core-api-with-firebase/…

标签: c# authentication asp.net-web-api asp.net-core firebase-authentication


【解决方案1】:

Firebase 使用 RSA256 非对称密钥加密系统,这意味着它具有公钥和私钥。 签名令牌使用私钥进行,而验证令牌使用公钥进行。

下图说明了令牌签名是如何发生的。

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

  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 会检查此令牌,并验证它是否有效(是否使用 Google 的私钥签名)。这里要意识到的重要一点是,为了进行验证,我们的 Api 不需要访问私钥。只有公钥是必要的。验证后,中间件会相应地填充HttpContext.UserHttpContext.User.Identity.IsAuthenticated

您可以在 RSA Wikipedia page 上找到对此概念的更简单描述,在 my blog post 上找到有关 Firebase + ASP.NET 的更多信息。

【讨论】:

【解决方案2】:

对于后端,有一个 Nuget 包可以为您解决问题:

安装包 AspNetCore.Firebase.Authentication

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

它负责受众、发行者、签名和有效性验证

【讨论】:

  • 不确定这是否适用于 ASP .NET Core 2.0。我收到以下错误:无法从程序集“Microsoft.AspNetCore.Authentication.JwtBearer, Version=2.0.0.0 加载类型“Microsoft.AspNetCore.Builder.JwtBearerOptions”
  • @Raphaël ApiKey 有什么用?
  • @TzviGregoryKaidanov 实际上它在 appsettings 中,但未使用,因为中间件仅验证令牌和签名,不需要 ApiKey
  • @Primico 我发布了一个 .netcore2.0 兼容包
  • 嗨@Raphaël,我在.Net Core 2.1 上使用你的nuget 包非常好。但它不适用于 .Net Core 3.1。你能帮我检查一下这个问题吗?
【解决方案3】:

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

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

【讨论】:

  • 发布了支持.aspnetcore2.0的包AspNetCore.Firebase.Authentication 2.0
猜你喜欢
  • 2023-04-01
  • 2017-09-11
  • 2018-06-22
  • 1970-01-01
  • 2019-06-24
  • 2019-10-30
  • 2021-06-15
  • 2020-01-30
  • 2020-01-17
相关资源
最近更新 更多