// Copyright Epic Games, Inc. All Rights Reserved. using System; using System.Diagnostics.CodeAnalysis; using System.IdentityModel.Tokens.Jwt; using System.Text.Json; using Microsoft.AspNetCore.Http; namespace HordeServer.Utilities { /// /// Helper functions for dealing with JWTs /// public static class JwtUtils { /// /// Gets the bearer token from an HTTP request /// /// The request to read from /// The bearer token prefix, ex. "Bearer " /// On success, receives the bearer token /// True if the bearer token was read public static bool TryGetBearerToken(HttpRequest request, string bearerPrefix, [NotNullWhen(true)] out string? token) { // Get the authorization header string? authorization = request.Headers.Authorization; if (String.IsNullOrEmpty(authorization)) { token = null; return false; } // Check if it's a bearer token if (!authorization.StartsWith(bearerPrefix, StringComparison.OrdinalIgnoreCase)) { token = null; return false; } // Get the token token = authorization.Substring(bearerPrefix.Length).Trim(); return true; } /// /// Tries to parse a JWT and check the issuer matches /// /// The token to parse /// On success, receives the parsed JWT /// True if the jwt was parsed public static bool TryParseJwt(string token, [NotNullWhen(true)] out JwtSecurityToken? jwtToken) { // Check if it's a JWT JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler(); if (!handler.CanReadToken(token)) { jwtToken = null; return false; } // Try to parse the JWT try { jwtToken = handler.ReadJwtToken(token); return true; } catch (JsonException) { jwtToken = null; return false; } } } }