API authentication with ASP.NET Core 3.0 and Firebase

API authentication with ASP.NET Core 3.0 and Firebase

Nowadays, creating a new web API is easy but securing it can quickly become a struggle.

Obviously we want to do it right, for the best value at the minimal cost, so creating and maintaining an authentication provider is not an option.

There are multiple ways to get a user store, the one we’ll be using is Firebase. It is free, easy to use and provides with all the options we need (like signing in with email/password or with a Google account).

This article provides with the minimal information to have it working, more complete source code is available on GitHub.

Firebase project

You need to register/authenticate and create a project in Firebase. It is free and will take only a few minutes.

Once the project is created, you can create a user to make quick tests. To do so, click on the “Authentication” link from the left menu and click on the “Add user” button.

Go to the project settings (from the wheel icon) and save important information for later: “Project ID” and “Web API Key”.

ASP.NET Core 3.0 API

.NET Core is an amazing technology which is free, cross-platform and open source with a huge community. Version 3.0 has just been released and filled the functionality gap with the original .NET Framework.

.NET Core 3.0 SDK is the only requirement, it must be installed on your computer. This is easy to check, just execute this command line: dotnet –version. If dotnet is unknown or the version is not at least 3.0.100 then you can install it from dot.net.

There are multiple ways to create a new .NET application, you can do it from the command line: dotnet new webapi –name MyApi, or you can look at the official documentation to do it in Visual Studio.

Before doing anything else, make sure the project compiles without error with dotnet build and it runs with dotnet run.

It’s surprising how very few files are needed to make it work, take a look if you’re not familiar with it!

Here are the steps to secure your API with Firebase.

  • Install packages (NuGet): Microsoft.AspNetCore.Authentication.JwtBearer
  • Update your Controllers to add [Authorize] attribute to your class or method.
  • Update the Startup class with the following add-ons.
public void ConfigureServices(IServiceCollection services)
{
    services
        .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
        {
            options.Authority = "https://securetoken.google.com/my-project-id";
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidIssuer = "https://securetoken.google.com/my-project-id",
                ValidateAudience = true,
                ValidAudience = "my-project-id",
                ValidateLifetime = true
            };
        });

      services.AddControllers();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseHttpsRedirection();

    app.UseRouting();

    app.UseAuthentication();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
 }

Make the test again on your API, you should have a nice 401 error (unauthorized). So how do I go from there?

Create a token

In order to test the API we need a valid token generated by Firebase. The easiest way to do this is use Firebase REST API thanks to the documentation.

If you’re not familiar with REST calls, you can use Postman which is a great free tool to do web calls (and save them in collections).

To do a log-in with email/password (the ones we created manually before), the URL for the POST request is https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=[API_KEY] and here is an example of request body (obviously change the email and password).

{
  "email": "myemail@address.changeme",
  "password": "mysecretpassword",
  "returnSecureToken": "true"
}

You should have a successful reply, assuming you provided with a valid token (limited in time) in the idToken field.

{
  "kind": "identitytoolkit#VerifyPasswordResponse",
  "localId": "****",
  "email": "****",
  "displayName": "",
  "idToken": "****",
  "registered": true,
  "refreshToken": "****",
  "expiresIn": "3600"
}

Secure call to the API

Here it is, the final step, you have everything to validate your API!

You can use Postman or any other web request tool. Or you can look at the code sample on how to add swagger to your API (a little more code but a little more fun 😎).

If you’re not familiar with JSON Web Token (JWT) there are many resources on the web but you can start by this website: jwt.io.

The very important information to know is the token is the key element that will secure the calls to the API and will give the user authentication information to the API (you can look at it in debug in Controllers through the User property).

In the REST call this token is located in the request Headers fields, called Authentication, with the value “Bearer xxxxx” where xxxx is the token.

That’s all for now, please leave a reply or contact me directly on Twitter if you have any question or remark.

Leave a Reply

Your email address will not be published. Required fields are marked *