public ErrorResponseException(ErrorResponseException e, string message) : base(message) { response = e.Response; ResponseString = e.ResponseString; }
public static async Task <string> GetOAuthToken(string baseUrl, string oauthSource, string apiKey) { if (oauthSource == null) { throw new ArgumentNullException("oauthSource"); } string serverRSAExponent = null; string serverRSAModulus = null; string challenge = null; // Note that at two tries will be needed in the normal case. // The first try will get back a challenge, // the second try will try authentication. If something goes wrong server-side though // (e.g. the server was just rebooted or the challenge timed out for some reason), we // might get a new challenge back, so we try a third time just in case. int tries = 0; while (true) { tries++; var handler = new HttpClientHandler(); using (var httpClient = new HttpClient(handler)) { httpClient.DefaultRequestHeaders.TryAddWithoutValidation("grant_type", "client_credentials"); httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json") { CharSet = "UTF-8" }); var data = string.Empty; if (string.IsNullOrEmpty(serverRSAExponent) == false && string.IsNullOrEmpty(serverRSAModulus) == false && string.IsNullOrEmpty(challenge) == false) { var exponent = OAuthHelper.ParseBytes(serverRSAExponent); var modulus = OAuthHelper.ParseBytes(serverRSAModulus); var apiKeyParts = GetApiKeyParts(apiKey); data = OAuthHelper.DictionaryToString(new Dictionary <string, string> { { OAuthHelper.Keys.RSAExponent, serverRSAExponent }, { OAuthHelper.Keys.RSAModulus, serverRSAModulus }, { OAuthHelper.Keys.EncryptedData, OAuthHelper.EncryptAsymmetric(exponent, modulus, OAuthHelper.DictionaryToString(new Dictionary <string, string> { { OAuthHelper.Keys.APIKeyName, apiKeyParts.ApiKeyName }, { OAuthHelper.Keys.Challenge, challenge }, { OAuthHelper.Keys.Response, OAuthHelper.Hash(string.Format(OAuthHelper.Keys.ResponseFormat, challenge, apiKeyParts.ApiSecret)) } })) } }); } var requestUri = oauthSource; var response = await httpClient.PostAsync(requestUri, new StringContent(data)).AddUrlIfFaulting(new Uri(requestUri)).ConvertSecurityExceptionToServerNotFound().ConfigureAwait(false); if (response.IsSuccessStatusCode == false) { // We've already tried three times and failed if (tries >= 3) { throw ErrorResponseException.FromResponseMessage(response); } if (response.StatusCode != HttpStatusCode.PreconditionFailed) { throw ErrorResponseException.FromResponseMessage(response); } var header = response.Headers.GetFirstValue("WWW-Authenticate"); if (header == null || header.StartsWith(OAuthHelper.Keys.WWWAuthenticateHeaderKey) == false) { throw new ErrorResponseException(response, "Got invalid WWW-Authenticate value"); } var challengeDictionary = OAuthHelper.ParseDictionary(header.Substring(OAuthHelper.Keys.WWWAuthenticateHeaderKey.Length).Trim()); serverRSAExponent = challengeDictionary.GetOrDefault(OAuthHelper.Keys.RSAExponent); serverRSAModulus = challengeDictionary.GetOrDefault(OAuthHelper.Keys.RSAModulus); challenge = challengeDictionary.GetOrDefault(OAuthHelper.Keys.Challenge); if (string.IsNullOrEmpty(serverRSAExponent) || string.IsNullOrEmpty(serverRSAModulus) || string.IsNullOrEmpty(challenge)) { throw new InvalidOperationException("Invalid response from server, could not parse raven authentication information: " + header); } continue; } using (var stream = await response.GetResponseStreamWithHttpDecompression().ConfigureAwait(false)) using (var reader = new StreamReader(stream)) { var currentOauthToken = reader.ReadToEnd(); return(currentOauthToken); } } } }