diff --git a/src/Multifactor.Radius.Adapter.v2.Application/Features/PacketHandler/UseCases/SecondFactor/Multifactor/MultifactorApiService.cs b/src/Multifactor.Radius.Adapter.v2.Application/Features/PacketHandler/UseCases/SecondFactor/Multifactor/MultifactorApiService.cs index 8f2f303..fb6d49e 100644 --- a/src/Multifactor.Radius.Adapter.v2.Application/Features/PacketHandler/UseCases/SecondFactor/Multifactor/MultifactorApiService.cs +++ b/src/Multifactor.Radius.Adapter.v2.Application/Features/PacketHandler/UseCases/SecondFactor/Multifactor/MultifactorApiService.cs @@ -292,6 +292,7 @@ private SecondFactorResponse ProcessMfException( if (IsUserPassThrow(context)) { + LogApiUnreachableBypass(context, identity); var code = ConvertToAuthCode(AccessRequestResponse.Bypass); return new SecondFactorResponse(code); } @@ -299,6 +300,23 @@ private SecondFactorResponse ProcessMfException( return new SecondFactorResponse(radCode); } + private void LogApiUnreachableBypass(RadiusPipelineContext context, string identity) + { + var callingStationIdAttributeName = context.ClientConfiguration.CallingStationIdAttribute; + var callingStationIdAttr = context.RequestPacket.GetCallingStationIdAttribute(callingStationIdAttributeName); + var callingStationId = RequestDataExtractor.GetCallingStationId( + callingStationIdAttr, + context.RequestPacket.RemoteEndpoint, + context.ClientConfiguration.IsIpFromUdp); + + _logger.LogInformation( + "Bypass second factor for user '{user:l}' with calling-station-id {csi:l} from {host:l}:{port} because Multifactor API is unreachable", + identity, + callingStationId, + context.RequestPacket.RemoteEndpoint.Address, + context.RequestPacket.RemoteEndpoint.Port); + } + private bool IsUserPassThrow(RadiusPipelineContext context) { if (!context.ClientConfiguration.BypassSecondFactorWhenApiUnreachable) @@ -343,4 +361,4 @@ private SecondFactorResponse ProcessException(Exception ex, string identity, IPE private static bool ShouldCacheResponse(bool apiResponseCacheEnabled, AuthenticationStatus responseCode, AccessRequestResponse? response) => apiResponseCacheEnabled && responseCode == AuthenticationStatus.Accept && !(response?.Bypassed ?? false); -} \ No newline at end of file +} diff --git a/src/Multifactor.Radius.Adapter.v2.Infrastructure/Features/PacketHandler/UseCases/SecondFactor/CreateAccessRequest.cs b/src/Multifactor.Radius.Adapter.v2.Infrastructure/Features/PacketHandler/UseCases/SecondFactor/CreateAccessRequest.cs index 3754557..ea15f8b 100644 --- a/src/Multifactor.Radius.Adapter.v2.Infrastructure/Features/PacketHandler/UseCases/SecondFactor/CreateAccessRequest.cs +++ b/src/Multifactor.Radius.Adapter.v2.Infrastructure/Features/PacketHandler/UseCases/SecondFactor/CreateAccessRequest.cs @@ -51,7 +51,9 @@ public async Task Execute(AccessRequestDto dto, Multifact catch (TaskCanceledException) when (!cancellationToken.IsCancellationRequested) { _logger.LogWarning("Multifactor API timeout expired for endpoint: {Url}", Url); - return CreateDeniedResponse("Request timeout"); + throw new MultifactorApiUnreachableException( + $"Multifactor API timeout expired for endpoint: {Url}. " + + $"Host: {client.BaseAddress?.OriginalString}. Reason: Request timeout"); } catch (OperationCanceledException) { @@ -144,4 +146,4 @@ private HttpClient CreateClient(MultifactorAuthData authData) return client; } -} \ No newline at end of file +} diff --git a/src/Multifactor.Radius.Adapter.v2.Infrastructure/Features/PacketHandler/UseCases/SecondFactor/SendChallengeAsync.cs b/src/Multifactor.Radius.Adapter.v2.Infrastructure/Features/PacketHandler/UseCases/SecondFactor/SendChallengeAsync.cs index 6563859..1ba67ce 100644 --- a/src/Multifactor.Radius.Adapter.v2.Infrastructure/Features/PacketHandler/UseCases/SecondFactor/SendChallengeAsync.cs +++ b/src/Multifactor.Radius.Adapter.v2.Infrastructure/Features/PacketHandler/UseCases/SecondFactor/SendChallengeAsync.cs @@ -49,7 +49,9 @@ public async Task Execute(ChallengeRequestDto dto, Multif catch (TaskCanceledException) when (!cancellationToken.IsCancellationRequested) { _logger.LogWarning("Multifactor API timeout expired for endpoint: {Url}", Url); - return CreateDeniedResponse("Request timeout"); + throw new MultifactorApiUnreachableException( + $"Multifactor API timeout expired for endpoint: {Url}. " + + $"Host: {client.BaseAddress?.OriginalString}. Reason: Request timeout"); } catch (OperationCanceledException) { @@ -142,4 +144,4 @@ private HttpClient CreateClient(MultifactorAuthData authData) return client; } -} \ No newline at end of file +}