Supabase Auth with ASP.NET

Supabase is a very powerful tool. The authentication system is something I find particularly interesting. The free tier allows you to have 50,000 active users per month. More interesting in terms of price than certain specialized solutions like Auth0 / Clerk.

Start with NuGet

First of all, we need some NuGet packages:

  • System.IdentityModel.Tokens.Jwt
  • Microsoft.AspNetCore.Authentication.JwtBearer

There's no need to elaborate, just download them from Visual Studio. They will be useful for the code that follows.

Setup in your project

You can now add this code inside your Program.cs:

// Configure authentication
var supabaseUrl = Environment.GetEnvironmentVariable("SUPABASE_URL")
    ?? builder.Configuration.GetSection("Supabase").GetSection("Url").Value;
var supabaseSignatureStr = Environment.GetEnvironmentVariable("SUPABASE_SIGNATURE")
    ?? builder.Configuration.GetSection("Supabase").GetSection("Signature").Value;

if (supabaseSignatureStr == string.Empty)
    throw new Exception("Supabase signature is empty");

var supabaseSignatureKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(supabaseSignatureStr!));
var validIssuer = supabaseUrl + "/auth/v1";
var validAudiences = new List<string>() { "authenticated" };

builder.Services.AddAuthentication().AddJwtBearer(o =>
{
    o.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = supabaseSignatureKey,
        ValidAudiences = validAudiences,
        ValidIssuer = validIssuer
    };
});

The code is really easy. Nothing fancy. Like you can see, you have to define SUPABASE_URL and SUPABASE_SIGNATURE.

To validate the JWT token coming from Supabase, you need the signing key. You can get it from the SQL Editor of your Supabase project dashboard with the following SQL Query show app.settings.jwt_secret;.

Bonus: Get some user informations

It can be useful to consume informations inside the JWT token. To do that, here a code snippet:

public static class UserHelpers
{
    private struct UserMetadata
    {
        public string avatar_url { get; set; }
        public string full_name { get; set; }
    };

    public static string? GetId(this ClaimsPrincipal principal)
    {
        var userIdClaim = principal.FindFirst(c => c.Type == ClaimTypes.NameIdentifier) ?? principal.FindFirst(c => c.Type == "sub");
        if (userIdClaim != null && !string.IsNullOrEmpty(userIdClaim.Value))
        {
            return userIdClaim.Value;
        }

        return null;
    }

    public static string? GetName(this ClaimsPrincipal principal)
    {
        var metadataClaim = principal.FindFirst(c => c.Type == "user_metadata");
        if (metadataClaim != null)
        {
            var metadata = JsonSerializer.Deserialize<UserMetadata>(metadataClaim.Value);
            if (metadata.full_name != null && !string.IsNullOrEmpty(metadata.full_name))
            {
                return metadata.full_name;
            }
        }

        return null;
    }
}

And thanks to this helper, you can get some informations about the currently log in user like that :

var userId = User.GetId();
var userName = User.GetName();

Of course, you can extend it, get the avatar url, email, etc...
And voilà! You have everything to use Supabase Auth in your ASP.NET project.