A .NET library for managing authentication, backed by PropelAuth.
PropelAuth makes it easy to add authentication and authorization to your B2B/multi-tenant application.
Your frontend gets a beautiful, safe, and customizable login screen. Your backend gets easy authorization with just a few lines of code. You get an easy-to-use dashboard to config and manage everything.
dotnet add package PropelAuth
Begin by navigating to the Backend Integration page of the PropelAuth Dashboard and copying your Auth URL and Public Verifier Key. These values will be used to validate access tokens generated by your frontend. Paste these values into your .NET project.
var AUTH_URL = "https://auth.example.com";
var PUBLIC_KEY = @"-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1DsxqIjXqM0i5PL6kFVa
280S3gl96n2YlO6l9ss2XD/GOoDM11LxnwlIBWFXeRGhOVi4dp2pefY4Bh2rg4Z8
/Nq1J..
-----END PUBLIC KEY-----
";
We'll be using the System.Security.Cryptography Namespace to import the Public Verifier Key.
using System.Security.Cryptography;
var rsa = RSA.Create();
rsa.ImportFromPem(PUBLIC_KEY);
Next, let's configure our app to use JWT authentication. This will allow us to validate access tokens and retrieve user information from them.
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = false,
ValidAlgorithms = new List<string>() {"RS256"},
ValidIssuer = AUTH_URL,
IssuerSigningKey = new RsaSecurityKey(rsa),
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
};
});
The PropelAuth
.NET library provides a User Class to validate the access token and provide the user's information if it is valid. To get the User Class, use the GetUser()
method on the ClaimsPrincipal Class.
If the access token is not valid, the user's properties will be set to null. If that's the case, you can use .NET's Results Class to return a 401 Unauthorized
error.
using PropelAuth.Models;
using System.Security.Claims;
app.MapGet("/", (ClaimsPrincipal claimsPrincipal) =>
{
var user = claimsPrincipal.GetUser();
if (user == null)
{
return Results.Unauthorized();
}
return Results.Ok($"Hello user with ID {user.userId}");
});
Verifying the access token doesn't require an external request.
You can also verify which organizations the user is in, and which roles and permissions they have in each organization.
Verify that the request was made by a valid user and that the user is a member of the specified organization.
app.MapGet("/api/org/{orgId}", (ClaimsPrincipal claimsPrincipal, string orgId) =>
{
var user = claimsPrincipal.GetUser();
if (user == null)
{
return Results.Unauthorized();
}
var org = user.GetOrg(orgId);
if (org == null)
{
return Results.Forbid();
}
return Results.Ok($"You are in {org.orgName}");
});
Similar to checking org membership, but will also verify that the user has a specific Role in the organization.
A user has a Role within an organization. By default, the available roles are Owner, Admin, or Member, but these can be configured. These roles are also hierarchical, so Owner > Admin > Member.
app.MapGet("/api/org/{orgId}", (ClaimsPrincipal claimsPrincipal, string orgId) =>
{
var user = claimsPrincipal.GetUser();
if (user == null)
{
return Results.Unauthorized();
}
var org = user.GetOrg(orgId);
if (org != null && org.IsRole("Admin"))
{
return Results.Ok($"You are in {org.orgName}");
}
return Results.Forbid();
});
Similar to checking org membership, but will also verify that the user has the specified permission in the organization.
Permissions are arbitrary strings associated with a role. For example, can_view_billing
, ProductA::CanCreate
, and ReadOnly
are all valid permissions. You can create these permissions in the PropelAuth dashboard.
app.MapGet("/api/org/{orgId}", (ClaimsPrincipal claimsPrincipal, string orgId) =>
{
var user = claimsPrincipal.GetUser();
if (user == null)
{
return Results.Unauthorized();
}
var org = user.GetOrg(orgId);
if (org != null && org.HasPermission("can_view_billing"))
{
return Results.Ok($"You are allowed to view billing information for org {org.orgName}");
}
return Results.Forbid();
});
Feel free to reach out at support@propelauth.com