Skip to content

Instantly share code, notes, and snippets.

@smaglio81
Created June 28, 2020 15:51
Show Gist options
  • Save smaglio81/1ccd98789d960639d26a9d82556db123 to your computer and use it in GitHub Desktop.
Save smaglio81/1ccd98789d960639d26a9d82556db123 to your computer and use it in GitHub Desktop.
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.IdentityModel.JsonWebTokens;
using Nito.AsyncEx;
namespace YourProject
{
public interface IAtlassianOAuthCredentialsManager
{
Task<string> GetJwtAsync();
Task RefreshJwtAsync();
}
private readonly IAtlassianOAuthenticator _authenticator;
private readonly AsyncReaderWriterLock _jwtLock = new AsyncReaderWriterLock();
private AtlassianOAuthTokenResponse _tokenResponse = null;
private DateTime? _validTo = null;
public AtlassianOAuthCredentialsManager(
IAtlassianOAuthenticator authenticator
)
{
_authenticator = authenticator;
}
public async Task<string> GetJwtAsync()
{
if (await ShouldRefreshJwtAsync())
{
await RefreshJwtAsync();
}
string result;
using (await _jwtLock.ReaderLockAsync())
{
result = _tokenResponse.access_token; // should make an immutable copy
}
return result;
}
public async Task<AtlassianOAuthTokenResponse> GetCurrentTokenResponse()
{
using (await _jwtLock.ReaderLockAsync())
{
var result = new AtlassianOAuthTokenResponse()
{
access_token = _tokenResponse.access_token,
scope = _tokenResponse.scope,
expires_in = _tokenResponse.expires_in,
token_type = _tokenResponse.token_type
};
return result;
}
}
private async Task<bool> ShouldRefreshJwtAsync()
{
using(await _jwtLock.ReaderLockAsync()) {
if (_tokenResponse == null) return true;
if (_validTo == null) return true;
if (DateTime.Now >= _validTo.Value) return true;
return false;
}
}
public async Task RefreshJwtAsync()
{
using(await _jwtLock.WriterLockAsync()) {
var response = await _authenticator.AuthenticateAsync();
SetJwt(response);
}
}
private void SetJwt(AtlassianOAuthTokenResponse tokenResponse)
{
_tokenResponse = tokenResponse;
var jwtHandler = new JsonWebTokenHandler();
var token = jwtHandler.ReadJsonWebToken(_tokenResponse.access_token);
// https://developer.atlassian.com/cloud/jira/software/integrate-jsw-cloud-with-onpremises-tools/
// Write your code to anticipate that a granted token might no longer work. For example,
// track the expiration time and request a new token before the existing one expires
// (at least 30-60 seconds prior).
_validTo = token.ValidTo.AddMinutes(-1);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment