A simple demonstration about how a 3rd party user authentication service, Kinde in this case, can be used to authorize API requests between a React client and an ASP.NET Core web server with JSON Web Token (JWT).
First, the client must perform authentication with Kinde in order to gain an access token (JWT). The access token can be then be passed as Bearer Token in API requests to the server, which verifies the access token using a JSON Web Key (JWK) from Kinde.
In total, the authentication/authorization consists of four parts:
- The server requests a JSON Web Key Set (JWKS) from Kinde in order to verify JWTs.
- The client performs authentication with Kinde in order to gain access token (JWT).
- The client makes an API request to the server, passing the access token as Bearer Token.
- The server uses a JWK from the JWKS to verify the JWT passed as Bearer Token.
Auth flow diagram:
Both, the server and the client, must be started separately!
Instructions on how to setup Kinde can be found from Kinde Docs.
Required Kinde resources:
- Kinde account and business
- An application ("SPA or Mobile Application")
- An API that's linked to the application
- At least one user
- (OPTIONAL: Social logins)
-
Create
appsettings.Development.jsonfile underserver/Server/(if it doesn't exists) and add your Kinde URL to it:{ "KINDE_URL": "https://your-business.kinde.com" } -
Start the server in development mode (in order to read Kinde URL from
appsettings.Development.json):ASPNETCORE_ENVIRONMENT=Development dotnet run
-
Create
.envfile underclient/(if it doesn't exists) and the following variables to it:VITE_API_URL=http://localhost:8080 VITE_KINDE_URL=https://your-business.kinde.com VITE_KINDE_CLIENT_ID=your-kinde-client-id -
Install npm dependencies:
npm i
-
Start the client:
npm run dev
-
Press
To Loginto start authentication with Kinde :)
In the end, using a JWK(S) to validate JWT issuer in .NET turned out to be simple and effortless.
The following code snippet demonstrates how to use JWKS from Kinde to validate JWTs in .NET:
var kindeUrl = "https://your-business.kinde.com";
// ...
// 1. Request JWKS from Kinde.
using HttpClient client = new();
var res = await client.GetAsync($"{kindeUrl}/.well-known/jwks");
var jsonStr = await res.Content.ReadAsStringAsync();
var jwks = new JsonWebKeySet(jsonStr);
// ...
// 2. Create JWT validation parameters with the JWKS.
var jwtValidationParams = new TokenValidationParameters()
{
// Validate both, the issuer and its signing key.
ValidateIssuer = true,
ValidateIssuerSigningKey = true,
ValidIssuer = kindeUrl,
IssuerSigningKey = jwks.Keys.First() // <-- The first JWK is used here!
// ...
};
// ...
// 3. Use the JWT validation parameters.
// (This repo uses ASP.NET Core middleware to validate JWTs.)