I use Azure AD B2C to login on a React Native app. This app can make API calls to a CMS (Strapi). Before returning a response, the CMS has to check that the user that makes the request is logged in.
The login part in the app is working fine, this is the data that I get back in the app after logging in:
{
"tokenType": "Bearer",
"refreshToken": "...",
"scope": "offline_access openid",
"idToken": "...",
"issuedAt": 1698310667
}
The app then sends the idToken in the header x-activedirectory-token
.
I am lost on how to check the validity of the token in the CMS policy (middleware). I tried the @azure/msal-node package, but failed to find a method to just check if the token is valid.
These Azure docs on the subject setup an Express-Passport middleware, but Strapi uses a different router (koa), and adding a middleware in middleware seems weird.
The preferred solution would be something like the @azure/msal-node package that can check the token, or some Azure endpoint or something similar.
Maybe I'm overlooking something, because I have little to no Azure AD experience. That being said, any help is very appreciated, since I've been stuck on this for a while now.
Thank you @juunas for pointing me in the right direction. I managed to get the required behaviour by using the jwks-rsa and jsonwebtoken libraries. A code sample of how this worked (based on a code example in the jsonwebtoken readme):
import {
verify as verifyJwt,
type JwtHeader,
type SigningKeyCallback,
} from "jsonwebtoken";
import jwksClient from "jwks-rsa";
// Gets the cookie information from the discovery document
const client = jwksClient({
jwksUri: "https://.../discovery/v2.0/keys?p=b2c_1_signin",
});
function getPublicKey(header: JwtHeader, callback: SigningKeyCallback) {
client.getSigningKey(header.kid, function (err, key) {
let signingKey = key.getPublicKey();
if (!signingKey && "rsaPublicKey" in key && key.rsaPublicKey) {
signingKey = key.rsaPublicKey;
}
callback(null, signingKey);
});
}
// Verify the token with the public key, constructed by the jwksClient
verifyJwt(activeDirectoryToken, getPublicKey, {}, (err) => {
if (err) {
// Invalid token
return;
}
// Valid token
});