c# - 使用 .NET Core 的 Firebase 身份验证 (JWT)

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

我正在开发一个简单的 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);
        });
    }

接下来,我使用 token 并通过 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<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 在 Controller 中为 true),但我认为不应该。我的问题是我不完全确定这是安全的。

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

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

最佳答案

Firebase 使用 RSA256 非对称 key 密码系统,这意味着它有公钥和私钥。 签署 token 使用私钥,而验证 token 使用公钥。

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

enter image description here

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

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

您可以在 RSA Wikipedia page 上找到关于这个概念的更简单的描述。 ,以及有关 Firebase + ASP.NET 的更多信息,请参见 my blog post .

关于c# - 使用 .NET Core 的 Firebase 身份验证 (JWT),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42336950/

相关文章:

c# - 格式化小数 xamarin

C# 将字符串中每个句子的第一个字母大写

node.js - 使用 Passport Consumer 策略设置全局 session

ruby - sinatra-authentication gem 不是在寻找正确的 View 吗?

c# - 简单注入(inject)器无法在 Web API Controller 中注入(inject)依赖项

c# - 如何使用 Microsoft ASP.NET Web API OData 中的 Delta<T> 和 Code First\JsonMediaTypeFormatter

c# - WebClient.DownloadString 慢?

c# - 在 C# 中使用 MakeGenericMethod 后如何制作具体类型?

authentication - 在 NextJs getInitialProps 中获取 localStorage

c# - 在 asp.net core web api 中获取 Request.Form.Files 始终为空