Firebase Authentication (JWT) with .NET Core

I am developing a simple API that handles Authentication performed by Firebase for later use with Android clients.

So, in the Firebase console, I turned on the login methods on Facebook and Google and created a sample html page that I can use to check the login method - this next function is called by the button:

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); }); } 

next I use a token and send it to my API using a simple ajax call from jQuery here:

 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; } }); } 

Next stop: API backend - written with .NET Core.

In the “Startup” section, I configured JwtBearer Auth ( Microsoft.AspNetCore.Authentication.JwtBearer package):

 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, }, }); 

And here is the controller code - with the [Authorize] attribute:

 [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 ( HttpContext.User.Identity.IsAuthenticated is true inside the controller), but I think it shouldn't. My problem is that I'm not entirely sure that it is safe.

How to verify the JWT token signature part? I saw many code examples describing the x509 or RS256 algorithm, where do they fit? Should I check any certificate or private key with IssuerSigningKey or TokenDecryptionKey from the TokenValidationParameters class? What am I missing?

Relevant sources of knowledge about the problem:

+5
source share
3 answers

Firebase uses an asymmetric RSA256 cryptosystem, which means that it has a public and private key. The token is signed with the private key, and the token is checked with the public key.

The following diagram illustrates how a token is signed.

enter image description here

The following steps are used during login and access to the secure endpoint.

  • When our application starts (and then also periodically later), JwtBearerMiddleware calls https://securetoken.google.com/my-firebase-project/.well-known/openid-configuration , where it can access the current Google public keys. It is important that when we use an asymmetric cryptosystem with a public key, the public key is not kept secret, but is published in plain sight.
  • The client subscribes using their credentials through Firebase (these are the client’s own credentials, they have nothing to do with the key used to sign the token).
  • If the signin was successful, Firebase builds a JWT token for the client. The most important part of this token is that it is signed using the private key of the key pair . Unlike a public key, a private key is never published publicly, it is stored as a secret in the Google infrastructure.
  • The client receives the JWT token.
  • The client invokes a secure endpoint on our Api and places the token in the Authorization header. At this point, JwtBearerMiddleware in the pipeline checks this token and checks if it is valid (if it was signed with a Google private key). It is important to understand that for verification we should not have access to the private key. For this, you only need a public key. After verification, the middleware populates HttpContext.User and HttpContext.User.Identity.IsAuthenticated respectively.

You can find an even simpler description of this concept on my blog post page.

+13
source

NuGet uses the old authentication mechanism ASP.NET Core 1.x.

Authentication has been changed: https://docs.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/identity-2x

+1
source

For the inside, there is a Nuget package that does the trick for you:

AspNetCore.Firebase.Authentication installation package

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

This is a check of the audience, issuer, signature and validity

0
source

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


All Articles