private string GetJwt(OAuth2Params oauthParams)
        {
            _fileReader.Open(oauthParams.CertificateFilePath);
            var pemReader = new PemReader(_fileReader.Reader);
            var keyPair   = (AsymmetricCipherKeyPair)pemReader.ReadObject();
            var rsaParams = DotNetUtilities.ToRSAParameters((RsaPrivateCrtKeyParameters)keyPair.Private);

            var rsa = new RSACryptoServiceProvider(2048);

            rsa.ImportParameters(rsaParams);

            var tokenHandler = new JwtSecurityTokenHandler();
            var now          = DateTime.UtcNow;

            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new[]
                {
                    new Claim("scope", oauthParams.ScopesAsString())
                }),
                Issuer             = oauthParams.ClientId,
                Audience           = oauthParams.Audience,
                Expires            = now.AddHours(1),
                SigningCredentials = new SigningCredentials(new RsaSecurityKey(rsa), "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256")
            };

            return(tokenHandler.CreateEncodedJwt(tokenDescriptor));
        }
        public async Task <AccessToken> GetAccessTokenAsync(OAuth2Params oauthParams)
        {
            var jwt = GetJwt(oauthParams);

            var form = new FormUrlEncodedContent(new []
            {
                new KeyValuePair <string, string>("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer"),
                new KeyValuePair <string, string>("assertion", jwt),
                new KeyValuePair <string, string>("client_id", oauthParams.ClientId),
                new KeyValuePair <string, string>("client_secret", oauthParams.ClientSecret)
            });

            var request = new HttpRequestMessage(HttpMethod.Post, oauthParams.AuthServerUri)
            {
                Content = form
            };

            request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            var response = await _httpClient.SendAsync(request);

            if (!response.IsSuccessStatusCode)
            {
                throw new WebException($"Unable to obtain an access token. HTTP Status Code: {response.StatusCode}");
            }

            var content = JObject.Parse(await response.Content.ReadAsStringAsync());

            return(new AccessToken
            {
                Token = content["access_token"].Value <string>(),
                Expires = DateTime.UtcNow.AddSeconds(content["expires_in"].Value <int>())
            });
        }