public class AuthenticatingHandler : DelegatingHandler where T : ISecurityTokenAccessor { private readonly Policy _policy; private readonly T _securityTokenAccessor; private IAccessToken _accessToken; private AuthenticationHeaderValue _authenticationHeader; public AuthenticatingHandler(T securityTokenAccessor) { _securityTokenAccessor = securityTokenAccessor; // Create a policy that tries to renew the access token if a 403 Unauthorized is received. _policy = Policy.HandleResult(r => r.StatusCode == HttpStatusCode.Unauthorized).RetryAsync(1, async (response, attemp) => { await AuthenticateAsync(); }); } protected async override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { // Request an access token if we don't have one yet or if it has expired. if (!_securityTokenAccessor.ValidateAccessToken(_accessToken)) { await AuthenticateAsync(); } // Try to perform the request, re-authenticating gracefully if the call fails due to an expired or revoked access token. var result = await _policy.ExecuteAndCaptureAsync(() => { request.Headers.Authorization = _authenticationHeader; return base.SendAsync(request, cancellationToken); }); return result.Result; } private async Task AuthenticateAsync() { _accessToken = await _securityTokenAccessor.RenewAccessTokenAsync(); _authenticationHeader = new AuthenticationHeaderValue(_accessToken.TokenType, _accessToken.Token); } }