Skip to content

Commit

Permalink
feat: verify-token
Browse files Browse the repository at this point in the history
  • Loading branch information
KotaHusky committed Mar 30, 2024
1 parent 3d9e739 commit 222cdfe
Show file tree
Hide file tree
Showing 6 changed files with 202 additions and 36 deletions.
53 changes: 45 additions & 8 deletions apps/msal-react-demo/src/app/api/hello-msal/route.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,56 @@
import jwt from 'jsonwebtoken';
import jwksRsa from 'jwks-rsa';

const b2cAuthority = 'msalreact';
const policyNames = {
signUpSignIn: 'B2C_1_signup_signin',
forgotPassword: 'B2C_1_reset',
editProfile: 'B2C_1_edit_profile',
};

const jwksClient = jwksRsa({
jwksUri: `https://${b2cAuthority}.b2clogin.com/${b2cAuthority}.onmicrosoft.com/${policyNames.signUpSignIn}/discovery/v2.0/keys`,
});

const getSigningKey = (header: any, callback: any) => {
jwksClient.getSigningKey(header.kid, (err: any, key: any) => {
if (err) {
callback(err, null);
} else {
const signingKey = key.publicKey || key.rsaPublicKey;
callback(null, signingKey);
}
});
};

async function verifyB2CToken(token: string) {
return new Promise((resolve, reject) => {
jwt.verify(token, getSigningKey, {
audience: process.env.NEXT_PUBLIC_AZURE_AD_CLIENT_ID,
issuer: `https://${b2cAuthority}.b2clogin.com/${process.env.NEXT_PUBLIC_AZURE_AD_TENANT_ID}/v2.0/`,
algorithms: ['RS256']
}, (err, decoded) => {
if (err) {
reject(err);
} else {
resolve(decoded);
}
});
});
}

export async function GET(request: Request) {
try {
// Extract the token from the Authorization header
const authHeader = request.headers.get('Authorization');
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return new Response('Unauthorized', { status: 401 });
return new Response('Unauthorized, missing or invalid token', { status: 401 });
}

const token = authHeader.substring(7); // Remove the "Bearer " prefix to get the actual token
const { verifyToken } = await import('@my-workspace/lib-msal-react');
await verifyToken(token); // Verify the token
const token = authHeader.split(' ')[1];
await verifyB2CToken(token);

// Proceed with your API logic after successful token verification
return new Response('Hello, from protected API!');
} catch (error) {
// Handle errors (e.g., token verification failure)
return new Response((error as Error).message || 'Error during token verification', { status: 401 });
}
}
}
2 changes: 1 addition & 1 deletion libs/lib-msal-react/src/lib/msal-react.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { AccountProvider } from './account-context/account-context';

const b2cAuthority = 'msalreact';

const policyNames = {
export const policyNames = {
signUpSignIn: 'B2C_1_signup_signin',
forgotPassword: 'B2C_1_reset',
editProfile: 'B2C_1_edit_profile',
Expand Down
52 changes: 52 additions & 0 deletions libs/lib-msal-react/src/lib/verify-token/verify-token.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import jwt from 'jsonwebtoken';
import jwksRsa from 'jwks-rsa';
import { policyNames } from '../msal-react';

// Assuming your b2cAuthority and policyNames are correctly configured
const b2cAuthority = 'msalreact';

// Initialize the JWKS client
const jwksClient = jwksRsa({
jwksUri: `https://${b2cAuthority}.b2clogin.com/${b2cAuthority}.onmicrosoft.com/${policyNames.signUpSignIn}/discovery/v2.0/keys`,
});

// Helper function to retrieve the signing key
const getSigningKey = (header: any, callback: any) => {
jwksClient.getSigningKey(header.kid, (err: any, key: any) => {
if (err) {
callback(err, null);
} else {
const signingKey = key.publicKey || key.rsaPublicKey;
callback(null, signingKey);
}
});
};

export async function verifyB2CToken(req: any, res: any) {
console.log('req:', req);
const token = req.headers.authorization?.split(' ')[1]; // Extract the token from the Authorization header
if (!token) {
return res.status(401).json({ message: 'Unauthorized - Token missing' });
}

try {
// Verify the token
jwt.verify(token, getSigningKey, {
audience: process.env.NEXT_PUBLIC_AZURE_AD_CLIENT_ID,
issuer: `https://${b2cAuthority}.b2clogin.com/${process.env.NEXT_PUBLIC_AZURE_AD_TENANT_ID}/v2.0/`,
algorithms: ['RS256']
}, (err, decoded) => {
if (err) {
// Handle verification errors
return res.status(401).json({ message: 'Unauthorized', error: err.message });
} else {
// Token is valid, proceed with your logic
res.status(200).json({ message: 'Authorized', decoded });
}
});
} catch (error: any) {
// Handle unexpected errors
res.status(500).json({ message: 'Server error', error: error.message });
}
}
27 changes: 0 additions & 27 deletions libs/lib-msal-react/src/lib/verify-token/verify-token.tsx

This file was deleted.

103 changes: 103 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"dependencies": {
"@azure/msal-browser": "^3.11.0",
"@azure/msal-react": "^2.0.13",
"azure-ad-verify-token": "^3.0.3",
"jsonwebtoken": "^9.0.2",
"jwks-rsa": "^3.1.0",
"next": "14.0.4",
Expand Down

0 comments on commit 222cdfe

Please sign in to comment.