Skip to content

Commit a1fd0a6

Browse files
committed
Handle 401 Unauthorized during token refresh
- Added try-catch for handling FlurlHttpException with status code 401 when refreshing tokens. - Clears stored tokens and improves error logging. - Updated SignalRHostedService to return null on failed token refresh, preventing continuous auth attempts and triggering reconnect. - Enhanced fallback behavior for network/server errors during token refresh.
1 parent 777ddfd commit a1fd0a6

File tree

2 files changed

+37
-13
lines changed

2 files changed

+37
-13
lines changed

ProReception.DistributionServerInfrastructure/HostedServices/SignalRHostedService.cs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -153,15 +153,23 @@ private async Task LoginAndCreateSignalRConnection(CancellationToken cancellatio
153153
current = await proReceptionApiClient.RefreshAndSaveTokens(current);
154154
logger.LogInformation("SignalR AccessTokenProvider: token refreshed");
155155
}
156+
catch (FlurlHttpException ex) when (ex.StatusCode == 401)
157+
{
158+
logger.LogError(ex, "SignalR AccessTokenProvider: Token refresh failed with 401 Unauthorized. Tokens have been cleared. Returning null to stop authentication attempts.");
159+
// Return null to signal authentication failure
160+
// This will cause SignalR connection to fail and trigger the Closed event
161+
// The Closed event handler will restart ExecuteStartUp which waits for new tokens
162+
return null;
163+
}
156164
catch (Exception ex)
157165
{
158-
logger.LogError(ex, "SignalR AccessTokenProvider: CRITICAL - failed to refresh token, using existing token");
159-
// Return existing token (may fail with 401 and trigger reconnect)
160-
// Don't throw - let SignalR handle the authentication failure and reconnect
166+
logger.LogError(ex, "SignalR AccessTokenProvider: Failed to refresh token due to network/server error, attempting with existing token");
167+
// For non-401 errors (network issues, server errors, etc.), try with existing token
168+
// It might work, or fail and trigger reconnect
161169
if (string.IsNullOrWhiteSpace(current.AccessToken))
162170
{
163-
logger.LogError("SignalR AccessTokenProvider: No valid token available, returning empty string");
164-
return string.Empty;
171+
logger.LogError("SignalR AccessTokenProvider: No valid token available, returning null");
172+
return null;
165173
}
166174
}
167175
}

ProReception.DistributionServerInfrastructure/ProReceptionApi/ApiClientBase.cs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,21 @@ public async Task<TokensRecord> RefreshAndSaveTokens(TokensRecord tokensRecord)
6969
{
7070
_logger.LogInformation("Refreshing ProReception tokens...");
7171

72-
var response = await _configuration.BaseUrl
73-
.AppendPathSegment("auth/refresh")
74-
.PostJsonAsync(new { tokensRecord.AccessToken, tokensRecord.RefreshToken })
75-
.ReceiveJson<TokenResponse>();
72+
try
73+
{
74+
var response = await _configuration.BaseUrl
75+
.AppendPathSegment("auth/refresh")
76+
.PostJsonAsync(new { tokensRecord.AccessToken, tokensRecord.RefreshToken })
77+
.ReceiveJson<TokenResponse>();
7678

77-
return await SaveTokensToSettings(response);
79+
return await SaveTokensToSettings(response);
80+
}
81+
catch (FlurlHttpException ex) when (ex.StatusCode == 401)
82+
{
83+
_logger.LogWarning("Token refresh failed with 401 Unauthorized. Clearing stored tokens.");
84+
await _settingsManagerBase.RemoveTokens();
85+
throw; // Re-throw so caller knows refresh failed
86+
}
7887
}
7988

8089
public async Task<T> Query<T>(Func<IFlurlRequest, Task<T>> getRequestFunc) =>
@@ -127,8 +136,15 @@ private async Task<string> GetAccessTokenAsync()
127136
return tokensRecord.AccessToken;
128137
}
129138

130-
var refreshedTokens = await RefreshAndSaveTokens(tokensRecord);
131-
132-
return refreshedTokens.AccessToken;
139+
try
140+
{
141+
var refreshedTokens = await RefreshAndSaveTokens(tokensRecord);
142+
return refreshedTokens.AccessToken;
143+
}
144+
catch (FlurlHttpException ex) when (ex.StatusCode == 401)
145+
{
146+
// Tokens were already cleared in RefreshAndSaveTokens
147+
throw new InvalidOperationException("Your session has expired. Please log in again.", ex);
148+
}
133149
}
134150
}

0 commit comments

Comments
 (0)