private string ComputeChallenge(AuthenticatorChallenge challenge, string apiKey) { if (string.IsNullOrEmpty(challenge.RSAExponent) || string.IsNullOrEmpty(challenge.RSAModulus) || string.IsNullOrEmpty(challenge.Challenge)) { throw new InvalidOperationException("Invalid authentication information"); } var apiKeyParts = ExtractApiKeyAndSecret(apiKey); var apiKeyName = apiKeyParts[0].Trim(); var apiSecret = apiKeyParts[1].Trim(); var data = OAuthHelper.DictionaryToString(new Dictionary <string, string> { { OAuthHelper.Keys.RSAExponent, challenge.RSAExponent }, { OAuthHelper.Keys.RSAModulus, challenge.RSAModulus }, { OAuthHelper.Keys.EncryptedData, OAuthHelper.EncryptAsymmetric(OAuthHelper.ParseBytes(challenge.RSAExponent), OAuthHelper.ParseBytes(challenge.RSAModulus), OAuthHelper.DictionaryToString(new Dictionary <string, string> { { OAuthHelper.Keys.APIKeyName, apiKeyName }, { OAuthHelper.Keys.Challenge, challenge.Challenge }, { OAuthHelper.Keys.Response, OAuthHelper.Hash(string.Format("{0};{1}", challenge, apiSecret)) } })) } }); return(data); }
private Tuple <HttpWebRequest, string> PrepareOAuthRequest(string oauthSource, string serverRSAExponent, string serverRSAModulus, string challenge) { #if !SILVERLIGHT var authRequest = (HttpWebRequest)WebRequest.Create(oauthSource); #else var authRequest = (HttpWebRequest)WebRequestCreator.ClientHttp.Create(new Uri(oauthSource)); #endif authRequest.Headers["grant_type"] = "client_credentials"; authRequest.Accept = "application/json;charset=UTF-8"; authRequest.Method = "POST"; if (!string.IsNullOrEmpty(serverRSAExponent) && !string.IsNullOrEmpty(serverRSAModulus) && !string.IsNullOrEmpty(challenge)) { var exponent = OAuthHelper.ParseBytes(serverRSAExponent); var modulus = OAuthHelper.ParseBytes(serverRSAModulus); var apiKeyParts = apiKey.Split(new[] { '/' }, StringSplitOptions.None); if (apiKeyParts.Length > 2) { apiKeyParts[1] = string.Join("/", apiKeyParts.Skip(1)); } if (apiKeyParts.Length < 2) { throw new InvalidOperationException("Invalid API key"); } var apiKeyName = apiKeyParts[0].Trim(); var apiSecret = apiKeyParts[1].Trim(); var 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, apiKeyName }, { OAuthHelper.Keys.Challenge, challenge }, { OAuthHelper.Keys.Response, OAuthHelper.Hash(string.Format(OAuthHelper.Keys.ResponseFormat, challenge, apiSecret)) } })) } }); return(Tuple.Create(authRequest, data)); } authRequest.ContentLength = 0; return(Tuple.Create(authRequest, (string)null)); }
private string ComputeChallenge(RavenJObject challengeJObject, string apiKey) { if (challengeJObject == null) { throw new InvalidDataException("Got null json object in ComputeChallenge"); } serverRSAExponent = challengeJObject.Value <string>(OAuthHelper.Keys.RSAExponent); serverRSAModulus = challengeJObject.Value <string>(OAuthHelper.Keys.RSAModulus); challenge = challengeJObject.Value <string>(OAuthHelper.Keys.Challenge); if (string.IsNullOrEmpty(serverRSAExponent) || string.IsNullOrEmpty(serverRSAModulus) || string.IsNullOrEmpty(challenge)) { throw new InvalidOperationException("Invalid authentication information"); } var apiKeyParts = ExtractApiKeyAndSecret(apiKey); var apiKeyName = apiKeyParts[0].Trim(); var apiSecret = apiKeyParts[1].Trim(); var data = OAuthHelper.DictionaryToString(new Dictionary <string, string> { { OAuthHelper.Keys.RSAExponent, serverRSAExponent }, { OAuthHelper.Keys.RSAModulus, serverRSAModulus }, { OAuthHelper.Keys.EncryptedData, OAuthHelper.EncryptAsymmetric(OAuthHelper.ParseBytes(serverRSAExponent), OAuthHelper.ParseBytes(serverRSAModulus), OAuthHelper.DictionaryToString(new Dictionary <string, string> { { OAuthHelper.Keys.APIKeyName, apiKeyName }, { OAuthHelper.Keys.Challenge, challenge }, { OAuthHelper.Keys.Response, OAuthHelper.Hash(string.Format(OAuthHelper.Keys.ResponseFormat, challenge, apiSecret)) } })) } }); return(data); }
public async Task <Action <HttpClient> > DoOAuthRequestAsync(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++; #if !SILVERLIGHT && !NETFX_CORE var handler = new WebRequestHandler(); #else var handler = new HttpClientHandler(); #endif var httpClient = new HttpClient(handler); httpClient.DefaultRequestHeaders.TryAddWithoutValidation("grant_type", "client_credentials"); httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json") { CharSet = "UTF-8" }); string data = null; if (!string.IsNullOrEmpty(serverRSAExponent) && !string.IsNullOrEmpty(serverRSAModulus) && !string.IsNullOrEmpty(challenge)) { var exponent = OAuthHelper.ParseBytes(serverRSAExponent); var modulus = OAuthHelper.ParseBytes(serverRSAModulus); var apiKeyParts = apiKey.Split(new[] { '/' }, StringSplitOptions.None); if (apiKeyParts.Length > 2) { apiKeyParts[1] = string.Join("/", apiKeyParts.Skip(1)); } if (apiKeyParts.Length < 2) { throw new InvalidOperationException("Invalid API key"); } var apiKeyName = apiKeyParts[0].Trim(); var apiSecret = apiKeyParts[1].Trim(); 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, apiKeyName }, { OAuthHelper.Keys.Challenge, challenge }, { OAuthHelper.Keys.Response, OAuthHelper.Hash(string.Format(OAuthHelper.Keys.ResponseFormat, challenge, apiSecret)) } })) } }); } var requestUri = oauthSource #if SILVERLIGHT .NoCache() #endif ; var response = await httpClient.PostAsync(requestUri, data != null?(HttpContent) new CompressedStringContent(data, true) : new StringContent("")) .AddUrlIfFaulting(new Uri(requestUri)) .ConvertSecurityExceptionToServerNotFound(); 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()) using (var reader = new StreamReader(stream)) { CurrentOauthToken = reader.ReadToEnd(); #if SILVERLIGHT BrowserCookieToAllowUserToUseStandardRequests(baseUrl, reader.ReadToEnd()); #endif return((Action <HttpClient>)(SetAuthorization)); } } }