Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dbeattie71/ede230a1a5c4fe6fad1a4cb94d125bf6 to your computer and use it in GitHub Desktop.
Save dbeattie71/ede230a1a5c4fe6fad1a4cb94d125bf6 to your computer and use it in GitHub Desktop.
public class AuthenticatingHandler<T> : DelegatingHandler where T : ISecurityTokenAccessor
{
private readonly Policy<HttpResponseMessage> _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<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.Unauthorized).RetryAsync(1, async (response, attemp) =>
{
await AuthenticateAsync();
});
}
protected async override Task<HttpResponseMessage> 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);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment