alancting/php-microsoft-jwt
Laravel/PHP helper for validating Microsoft (Azure AD) JWTs. Fetches and caches JWKS signing keys, verifies token signatures and claims, and supports common AAD scenarios so APIs can authenticate Microsoft identity tokens with minimal setup.
Installation
composer require alancting/php-microsoft-jwt
Add to composer.json under require if not using Composer globally.
First Use Case: Validate a Microsoft JWT
use Alancting\Microsoft\Jwt\Jwt;
$jwt = new Jwt();
$isValid = $jwt->validate('eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIs...');
Where to Look First
Alancting\Microsoft\Jwt\Jwt for core functionality.validate() method for basic validation.decode() method for extracting claims without validation.$jwt = new Jwt();
$decoded = $jwt->decode('token_here', true); // true = validate
if ($decoded) {
$claims = $decoded->getClaims();
$issuer = $claims['iss']; // e.g., "https://login.microsoftonline.com/"
}
use Alancting\Microsoft\Jwt\Jwt;
class MicrosoftAuthMiddleware
{
public function handle($request, Closure $next)
{
$jwt = new Jwt();
if (!$jwt->validate($request->bearerToken())) {
abort(401, 'Invalid Microsoft JWT');
}
return $next($request);
}
}
$decoded = $jwt->decode('token_here');
$userId = $decoded->getClaim('oid'); // Microsoft's user ID claim
$tenantId = $decoded->getClaim('tid'); // Tenant ID
try {
$jwt->validate('invalid_token');
} catch (\Alancting\Microsoft\Jwt\Exception\InvalidToken $e) {
// Handle invalid token
}
validate() in a custom guard or middleware.oid, tid) in the user session or database.$cacheKey = 'microsoft_jwt_' . md5($token);
$decoded = Cache::remember($cacheKey, now()->addMinutes(5), function () use ($jwt, $token) {
return $jwt->decode($token);
});
$decoded = $jwt->decode($token);
\Log::debug('Microsoft JWT Claims', $decoded->getClaims());
exp (expiration) claim manually if not using validate():
$exp = $decoded->getClaim('exp');
if ($exp < time()) {
throw new \RuntimeException('Token expired');
}
name). Handle missing keys gracefully:
$name = $decoded->getClaim('name', 'Anonymous');
RS256. If using other algorithms (e.g., HS256), configure explicitly:
$jwt = new Jwt(['algorithm' => 'HS256']);
$jwt->setLeeway(60); // 60 seconds
$decoded = $jwt->decode('token_here', false); // Skip validation
\Log::debug('Raw Claims', $decoded->getClaims());
iss)iss claim matches Microsoft’s expected value:
$issuer = $decoded->getClaim('iss');
if (!str_starts_with($issuer, 'https://login.microsoftonline.com/')) {
throw new \RuntimeException('Invalid issuer');
}
aud)aud claim matches your app’s client ID:
$aud = $decoded->getClaim('aud');
if ($aud !== config('services.microsoft.client_id')) {
throw new \RuntimeException('Invalid audience');
}
$jwt->setCustomValidator(function ($claims) {
if ($claims['iss'] !== 'https://login.microsoftonline.com/your-tenant') {
return false;
}
return true;
});
$jwt = new Jwt([
'algorithm' => 'RS256',
'leeway' => 30,
'issuer' => 'https://login.microsoftonline.com/'
]);
getUserPrincipalName()):
$upn = $decoded->getClaim('preferred_username');
How can I help you explore Laravel packages today?