/// <summary> /// Crear un nuevo cliente de OAuth. /// </summary> /// <param name="oAuthClientUris"> /// Contenedor de las URIs utilizadas para obtener Request Tokens, Access Token y Autorización del Usuario. /// </param> /// <param name="oAuthConsumerCredentials"> /// Conjunto de Consumer Key (API-Key de KMS) y Consumer Secret (API-Secret de KMS). /// </param> /// <param name="oAuthToken"> /// Conjunto de Token y Token Secret. /// </param> public OAuthClient( OAuthClientUris oAuthClientUris, OAuthCryptoSet oAuthConsumerCredentials = null, OAuthCryptoSet oAuthToken = null) { ClientUris = oAuthClientUris; Token = oAuthToken; ConsumerCredentials = oAuthConsumerCredentials; CurrentlyHasAccessToken = oAuthToken != null; }
/// <summary> /// Realiza el cambio o "canje" de un Request Token de OAuth por un Access Token, con permiso /// totales de acceso a la información del Usuario (o al menos aquellas autorizadas por el Usuario). /// </summary> /// <param name="verifier"> /// Verifier Code de OAuth /// </param> /// <returns> /// Conjunto de Access Token y Token Secret para peticiones subsecuentes. El /// </returns> public virtual OAuthCryptoSet ExchangeRequestToken(string verifier) { if (Token == null || CurrentlyHasAccessToken) { throw new OAuthUnexpectedRequest(); } if (string.IsNullOrEmpty(verifier)) { throw new ArgumentNullException("verifier"); } var response = RequestSimpleNameValue( HttpRequestMethod.POST, ClientUris.ExchangeTokenResource, new NameValueCollection { { "oauth_verifier", verifier } }); var token = response.Response.Get("oauth_token"); var tokenSecret = response.Response.Get("oauth_token_secret"); if (string.IsNullOrEmpty(token) || string.IsNullOrEmpty(tokenSecret)) { throw new OAuthUnexpectedResponse <NameValueCollection>(response); } Token = new OAuthCryptoSet( response.Response.Get("oauth_token"), response.Response.Get("oauth_token_secret")); CurrentlyHasAccessToken = true; return(Token); }
/// <summary> /// Genera una petición de generar un nuevo Request Token de OAuth, y devuelve la URL utilizada para /// continuar con el proceso de autorización de acceso OAuth por parte del Usuario. /// </summary> /// <returns> /// Devuelve un conjunto de Request Token y Token Secret /// </returns> public OAuthCryptoSet GetRequestToken(Dictionary <string, string> extraParameters = null) { var oAuthExtraParameters = new NameValueCollection(); Token = null; if (ClientUris == null) { throw new OAuthUnexpectedRequest(); } if (ClientUris.CallbackRequestTokenUri == null) { oAuthExtraParameters.Add("oauth_callback", "oob"); } else { oAuthExtraParameters.Add("oauth_callback", ClientUris.CallbackRequestTokenUri.AbsoluteUri); } var response = RequestSimpleNameValue( HttpRequestMethod.POST, ClientUris.RequestTokenResource, oAuthExtraParameters, oAuthExtraParameters.ToDictionary(false)); try { Token = new OAuthCryptoSet( response.Response.Get("oauth_token"), response.Response.Get("oauth_token_secret")); } catch (IndexOutOfRangeException) { throw new OAuthUnexpectedResponse(); } return(Token); }
/// <summary> /// Realiza una nueva petición OAuth al recurso especificado, y devuleve el objeto HttpWebResponse /// generado por la petición. /// </summary> /// <param name="requestMethod"> /// Método de Petición HTTP. /// </param> /// <param name="resource"> /// Recurso HTTP al que llamar (parte del URI después del dominio). /// </param> /// <param name="parameters"> /// Parámetros a enviar en la petición /// </param> /// <param name="oAuthExtraParameters"> /// Parámetros extra a añadir en la cabecera Authorization de OAuth. /// </param> /// <param name="requestHeaders"> /// Cabeceras HTTP a añadir a la petición. /// </param> /// <returns> /// Devuelve la respuesta recibida del API. /// </returns> public HttpWebResponse Request( HttpRequestMethod requestMethod, string resource, NameValueCollection parameters = null, Dictionary <string, string> oAuthExtraParameters = null, Dictionary <HttpRequestHeader, string> requestHeaders = null) { // -- Validar que se tengan API-Key -- if (ConsumerCredentials == null) { throw new OAuthConsumerKeySetInvalid(); } // -- Crear URI de Petición -- var requestUri = new Uri(ClientUris.BaseUri, resource); // -- Generar valores de cabecera OAuth -- // Calcular Timestamp UNIX (segundos desde 1970-01-01 00:00:00) TimeSpan timestamp = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0); // Calcular Nonce var nonceBytes = new byte[16]; (new Random()).NextBytes(nonceBytes); string nonce = Convert.ToBase64String(nonceBytes); // Generar valores de cabecera Authorization: OAuth var oAuthParameters = new NameValueCollection(); if (oAuthExtraParameters != null) { oAuthParameters.AddFromDictionary(oAuthExtraParameters); } oAuthParameters.Add( new NameValueCollection { { "oauth_consumer_key", ConsumerCredentials.Key }, { "oauth_nonce", nonce }, { "oauth_signature_method", SignatureMethod }, { "oauth_timestamp", ((int)timestamp.TotalSeconds).ToString() }, { "oauth_version", Version } }); if (Token != null && Token.Key != null) { oAuthParameters.Add("oauth_token", Token.Key); } // -- Generar base para Firma de Petición -- var oAuthSignatureBaseParameters = new NameValueCollection { oAuthParameters }; if (parameters != null) { oAuthSignatureBaseParameters.Add(parameters); } // -- Añadir Firma de Petición a cabecera Authorization: OAuth oAuthParameters.Add( "oauth_signature", GetSignature(requestMethod, requestUri, oAuthSignatureBaseParameters)); // -- Generar HttpWebRequest -- // Generar cuerpo de petición var requestStringBuilder = new StringBuilder(); if (parameters == null) { parameters = new NameValueCollection(); } foreach (string key in parameters.AllKeys) { var values = parameters.GetValues(key); if (values == null) { continue; } foreach (string value in values) { requestStringBuilder.Append( string.Format("{0}={1}&", Uri.EscapeDataString(key), Uri.EscapeDataString(value))); } } var requestString = ""; if (requestStringBuilder.Length > 0) { requestString = requestStringBuilder.ToString().Remove(requestStringBuilder.Length - 1); } // Preparar objeto de Petición Web if (requestMethod == HttpRequestMethod.GET && requestString.Length > 0) { requestUri = new Uri( string.Format( "{0}{1}{2}", requestUri.AbsoluteUri, requestUri.AbsoluteUri.IndexOf('?') > -1 ? "&" : "?", requestString)); } var request = (HttpWebRequest)WebRequest.Create(requestUri); request.Method = requestMethod.ToString(); if (requestHeaders != null) { foreach (var item in requestHeaders) { switch (item.Key) { case HttpRequestHeader.Accept: request.Accept = item.Value; break; case HttpRequestHeader.IfModifiedSince: request.IfModifiedSince = DateTime.Parse(item.Value); break; default: request.Headers.Add(item.Key, item.Value); break; } } } // Añadir cabecera Authorization: OAuth var oAuthHeaderString = new StringBuilder("OAuth "); foreach (string key in oAuthParameters.AllKeys) { var values = oAuthParameters.GetValues(key); if (values == null) { continue; } foreach (string value in values) { oAuthHeaderString.AppendFormat("{0}=\"{1}\", ", key, Uri.EscapeDataString(value)); } } request.Headers.Add( HttpRequestHeader.Authorization, oAuthHeaderString.ToString().Remove(oAuthHeaderString.Length - 2)); if (requestMethod != HttpRequestMethod.GET) { byte[] requestBodyBytes = Encoding.UTF8.GetBytes(requestString); request.ContentType = "application/x-www-form-urlencoded; charset=utf-8"; request.ContentLength = requestBodyBytes.Length; Stream requestBodyStream = request.GetRequestStream(); requestBodyStream.Write(requestBodyBytes, 0, requestBodyBytes.Length); requestBodyStream.Flush(); } // -- Solicitar y devolver respuesta de API -- try { return(request.GetResponse() as HttpWebResponse); } catch (WebException ex) { var response = ex.Response as HttpWebResponse; if (response == null) { throw new OAuthUnexpectedResponse(ex); } if (response.StatusCode != HttpStatusCode.Unauthorized) { return(response); } Token = null; CurrentlyHasAccessToken = false; if (response.Headers[HttpResponseHeader.Warning] == null) { throw new OAuthUnauthorized(response.StatusDescription, ex); } throw new OAuthUnauthorized(response.Headers[HttpResponseHeader.Warning], ex); } }