Checking Firebase.NET Token

Work on a project that uses Firebase for some data storage, and our client requests that the server be implemented with C # .NET. We configure REST endpoints on the server so that the client can communicate with it for several purposes (for example, running an algorithm to run, which can only be performed on the server).

Firebase recommends identifying users through an identifier token, as indicated here: https://firebase.google.com/docs/auth/server/verify-id-tokens#verify_id_tokens_using_a_third-party_jwt_library

Since there is no official Firebase .NET SDK server that supports token authentication, we resorted to using a third-party JWT library for this: https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet

As stated in the Firebase documentation, we first generate the token to be sent to the server. After checking several fields in the token, we use the field kidto grab the public key from https://www.googleapis.com/robot/v1/metadata/x509/ securetoken@system.gserviceaccount.com

We looked at the documentation and StackOverflow for a long time, but we cannot find a way to use this public key for this, as indicated in the Firebase documentation:

Finally, make sure that the identifier token has been signed with the private key corresponding to the baby’s application. Take the public key from https://www.googleapis.com/robot/v1/metadata/x509/ securetoken@system.gserviceaccount.com and use the JWT library to verify the signature.

The Firebase documentation does not really provide any explanation for this, nor the documentation for the library that we use. Thus, we could not even get the basic idea of ​​how we could verify that the token was signed with a private key, when all that was given to us is a public key.

What would be the best way to verify that the token was actually signed with the correct private key?

+4
2

, - , System.IdentityModel.Tokens.Jwt Nuget :

class Program {
  static HttpClient client = new HttpClient();
  static void Main() { RunAsync().Wait(); }

  static async Task RunAsync() {
    string encodedJwt = "[TOKEN_TO_BE_VALIDATED]";
    // 1. Get Google signing keys
    client.BaseAddress = new Uri("https://www.googleapis.com/robot/v1/metadata/");
    HttpResponseMessage response = await client.GetAsync(
      "x509/securetoken@system.gserviceaccount.com");
    if (!response.IsSuccessStatusCode) { return; }
    var x509Data = await response.Content.ReadAsAsync<Dictionary<string, string>>();
    SecurityKey[] keys = x509Data.Values.Select(CreateSecurityKeyFromPublicKey).ToArray();
    // 2. Configure validation parameters
    const string FirebaseProjectId = "[FIREBASE_PROJECT_ID]";
    var parameters = new TokenValidationParameters {
      ValidIssuer = "https://securetoken.google.com/" + FirebaseProjectId,
      ValidAudience = FirebaseProjectId,
      IssuerSigningKeys = keys,
    };
    // 3. Use JwtSecurityTokenHandler to validate signature, issuer, audience and lifetime
    var handler = new JwtSecurityTokenHandler();
    SecurityToken token;
    ClaimsPrincipal principal = handler.ValidateToken(encodedJwt, parameters, out token);
    var jwt = (JwtSecurityToken)token;
    // 4.Validate signature algorithm and other applicable valdiations
    if (jwt.Header.Alg != SecurityAlgorithms.RsaSha256) {
      throw new SecurityTokenInvalidSignatureException(
        "The token is not signed with the expected algorithm.");
    }
  }
  static SecurityKey CreateSecurityKeyFromPublicKey(string data) {
    return new X509SecurityKey(new X509Certificate2(Encoding.UTF8.GetBytes(data)));
  }
}

:

using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Net.Http;
using System.Security.Claims;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
+5

Newtonsoft.JSON, ​​ , Microsoft, : https://gist.github.com/saltyJeff/41029c9facf3ba6159ac019c1a85711a

Verify(string token) , : , , null, .

+1

Source: https://habr.com/ru/post/1657161/


All Articles