namespace NATS.Server.Auth; public sealed class ExternalAuthCalloutAuthenticator : IAuthenticator { private readonly IExternalAuthClient _client; private readonly TimeSpan _timeout; public ExternalAuthCalloutAuthenticator(IExternalAuthClient client, TimeSpan timeout) { _client = client; _timeout = timeout; } public AuthResult? Authenticate(ClientAuthContext context) { using var cts = new CancellationTokenSource(_timeout); ExternalAuthDecision decision; try { decision = _client.AuthorizeAsync( new ExternalAuthRequest( context.Opts.Username, context.Opts.Password, context.Opts.Token, context.Opts.JWT), cts.Token).GetAwaiter().GetResult(); } catch (OperationCanceledException) { return null; } if (!decision.Allowed) return null; return new AuthResult { Identity = decision.Identity ?? context.Opts.Username ?? "external", AccountName = decision.Account, }; } }