// 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;
}
}
}
}