47 lines
1.5 KiB
C#

using System.Security.Cryptography;
using System.Text;
namespace CatherineLynwood.Services
{
public class AudioTokenService
{
private readonly string _secret;
private readonly int _expirySeconds;
public AudioTokenService(IConfiguration config)
{
_secret = config["AudioSecurity:HmacSecretKey"];
_expirySeconds = int.Parse(config["AudioSecurity:TokenExpirySeconds"]);
}
public string GenerateToken(string id, long expires)
{
var payload = $"{id}:{expires}";
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(_secret));
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(payload));
return Convert.ToBase64String(hash);
}
public bool IsValid(string id, long expires, string token)
{
if (DateTimeOffset.UtcNow.ToUnixTimeSeconds() > expires)
return false;
if (string.IsNullOrWhiteSpace(token))
return false;
var expected = GenerateToken(id, expires);
return CryptographicOperations.FixedTimeEquals(
Encoding.UTF8.GetBytes(expected),
Encoding.UTF8.GetBytes(token));
}
public string GenerateUrl(string id)
{
var expires = DateTimeOffset.UtcNow.ToUnixTimeSeconds() + _expirySeconds;
var token = GenerateToken(id, expires);
return $"/api/audio/secure-stream/{id}?expires={expires}&token={Uri.EscapeDataString(token)}";
}
}
}