A class to hold an OAuth response message.
Exemple #1
0
        /// <summary>
        ///   Acquire a request token, from the given URI, using the given
        ///   HTTP method.
        /// </summary>
        ///
        /// <remarks>
        ///   <para>
        ///     To use this method, first instantiate a new Oauth.Manager object,
        ///     then set the callback param (oauth["callback"]='oob'). After the
        ///     call returns, you should direct the user to open a browser window
        ///     to the authorization page for the OAuth-enabled service. Or,
        ///     you can automatically open that page yourself. Do this with
        ///     System.Diagnostics.Process.Start(), passing the URL of the page.
        ///     There should be one query param: oauth_token with the value
        ///     obtained from oauth["token"].
        ///   </para>
        ///   <para>
        ///     According to the OAuth spec, you need to do this only ONCE per
        ///     application.  In other words, the first time the application
        ///     is run.  The normal oauth workflow is:  (1) get a request token,
        ///     (2) use that to acquire an access token (which requires explicit
        ///     user approval), then (3) using that access token, invoke
        ///     protected services.  The first two steps need to be done only
        ///     once per application.
        ///   </para>
        ///   <para>
        ///     For Twitter, at least, you can cache the access tokens
        ///     indefinitely; Twitter says they never expire.  However, other
        ///     oauth services may not do the same. Also: the user may at any
        ///     time revoke his authorization for your app, in which case you
        ///     need to perform the first 2 steps again.
        ///   </para>
        /// </remarks>
        ///
        /// <seealso cref='AcquireAccessToken'>
        ///
        /// </example>
        /// <returns>
        ///   a response object that contains the entire text of the response,
        ///   as well as extracted parameters. This method presumes the
        ///   response is query-param encoded. In other words,
        ///   poauth_token=foo&something_else=bar.
        /// </returns>
        public OAuthResponse AcquireRequestToken(string uri, string method)
        {
            NewRequest();
            var authzHeader = GetAuthorizationHeader(uri, method);

            // prepare the token request
            var request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(uri);

            request.Headers.Add("Authorization", authzHeader);
            request.Method = method;

            using (var response = (System.Net.HttpWebResponse)request.GetResponse())
            {
                using (var reader = new System.IO.StreamReader(response.GetResponseStream()))
                {
                    var r = new OAuthResponse(reader.ReadToEnd());
                    this["token"] = r["oauth_token"];

                    // Sometimes the request_token URL gives us an access token,
                    // with no user interaction required. Eg, when prior approval
                    // has already been granted.
                    try
                    {
                        if (r["oauth_token_secret"] != null)
                        {
                            this["token_secret"] = r["oauth_token_secret"];
                        }
                    }
                    catch { }
                    return(r);
                }
            }
        }
Exemple #2
0
        /// <summary>
        ///   Acquire an access token, from the given URI, using the given
        ///   HTTP method.
        /// </summary>
        ///
        /// <remarks>
        ///   <para>
        ///     To use this method, you must first set the oauth_token to the value
        ///     of the request token.  Eg, oauth["token"] = "whatever".
        ///   </para>
        ///   <para>
        ///     According to the OAuth spec, you need to do this only ONCE per
        ///     application.  In other words, the first time the application
        ///     is run.  The normal oauth workflow is:  (1) get a request token,
        ///     (2) use that to acquire an access token (which requires explicit
        ///     user approval), then (3) using that access token, invoke
        ///     protected services.  The first two steps need to be done only
        ///     once per application.
        ///   </para>
        ///   <para>
        ///     For Twitter, at least, you can cache the access tokens
        ///     indefinitely; Twitter says they never expire.  However, other
        ///     oauth services may not do the same. Also: the user may at any
        ///     time revoke his authorization for your app, in which case you
        ///     need to perform the first 2 steps again.
        ///   </para>
        /// </remarks>
        ///
        /// <seealso cref='AcquireRequestToken()'/>
        ///
        /// <example>
        ///   <para>
        ///     This example shows how to request an access token and key
        ///     from Twitter. It presumes you've already obtained a
        ///     consumer key and secret via app registration. Requesting
        ///     an access token is necessary only the first time you
        ///     contact the service. You can cache the access key and
        ///     token for subsequent runs, later.
        ///   </para>
        ///   <code>
        ///   // the URL to obtain a temporary "request token"
        ///   var rtUrl = "https://api.twitter.com/oauth/request_token";
        ///   var oauth = new OAuth.Manager();
        ///   // The consumer_{key,secret} are obtained via registration
        ///   oauth["client_id"] = "~~~client_id~~~~";
        ///   oauth["client_secret"] = "~~~client_secret~~~";
        ///   oauth.AcquireRequestToken(rtUrl, "POST");
        ///   var authzUrl = "https://api.twitter.com/oauth/authorize?oauth_token=" + oauth["token"];
        ///   // Normally you'd want to pop this in a WebBrowser control.
        ///   // For the example only, we'll pop the URL in a separate browser.
        ///   System.Diagnostics.Process.Start(authzUrl);
        ///   // instruct the user to type in the PIN from that browser window
        ///   var pin = "...";
        ///   var atUrl = "https://api.twitter.com/oauth/access_token";
        ///   oauth.AcquireAccessToken(atUrl, "POST", pin);
        ///
        ///   // now, update twitter status using that access token
        ///   var appUrl = "http://api.twitter.com/1/statuses/update.xml?status=Hello";
        ///   var authzHeader = oauth.GenerateAuthzHeader(appUrl, "POST");
        ///   var request = (HttpWebRequest)WebRequest.Create(appUrl);
        ///   request.Method = "POST";
        ///   request.PreAuthenticate = true;
        ///   request.AllowWriteStreamBuffering = true;
        ///   request.Headers.Add("Authorization", authzHeader);
        ///
        ///   using (var response = (HttpWebResponse)request.GetResponse())
        ///   {
        ///     if (response.StatusCode != HttpStatusCode.OK)
        ///       MessageBox.Show("There's been a problem trying to tweet:" +
        ///                       Environment.NewLine +
        ///                       response.StatusDescription);
        ///   }
        ///   </code>
        /// </example>
        ///
        /// <param name="uri">The uri to the "access token" endpoint of
        /// the service that implements oauth.  For Twitter, this is
        /// "https://api.twitter.com/oauth/access_token".
        /// </param>
        ///
        /// <param name="method">The method you will use to send the
        /// message asking for an access token.  For Twitter, this
        /// should be "POST".
        /// </param>
        ///
        /// <param name="pin">The PIN returned by the "Application approval" page
        /// shown by Twitter.  It's a string of numeric digits, 7 or so digits in
        /// length.
        /// </param>
        ///
        /// <returns>
        ///   a response object that contains the entire text of the response,
        ///   as well as extracted parameters. This method presumes the
        ///   response is query-param encoded. In other words,
        ///   oauth_token=foo&amp;something_else=bar.
        /// </returns>
        public OAuthResponse AcquireAccessToken(string uri, string method, string pin = null)
        {
            //Tracing.Trace("AcquireAccessToken.");
            //NewRequest();
            //_params.Remove("callback"); // no longer needed
            //_params["verifier"] = pin;

            var authzHeader = GetAuthorizationHeader(uri, method);

            try
            {
                // prepare the token request
                var request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(uri);
                request.Headers.Add("Authorization", authzHeader);
                request.Headers.Add("Ocp-Apim-Subscription-Key", _params["subscription-key"]);
                request.ContentType = "application/x-www-form-urlencoded";
                request.Method      = method;

                var campaign_id = Uri.EscapeDataString(_params["campaign_id"]);
                var postData    = $"grant_type=client_credentials&campaign_id={campaign_id}";

                byte[] byteArray = Encoding.UTF8.GetBytes(postData);
                request.ContentLength = byteArray.Length;
                using (var requestBody = request.GetRequestStream())
                {
                    requestBody.Write(byteArray, 0, byteArray.Length);
                }

                using (var response = (System.Net.HttpWebResponse)request.GetResponse())
                {
                    using (var reader = new System.IO.StreamReader(response.GetResponseStream()))
                    {
                        var s = reader.ReadToEnd();
                        //Tracing.Trace("resp: {0}", s);
                        var r = new OAuthResponse(s);
                        this["access_token"] = r["access_token"];
                        this["token_type"]   = r["token_type"];
                        this["expires_in"]   = r["expires_in"];
                        //_params.Remove("verifier"); // not needed any longer
                        return(r);
                    }
                }
            }
            catch (Exception ex1)
            {
                //Tracing.Trace("Exception: {0}", ex1.ToString());
                //_params.Remove("verifier"); // not needed any longer
                return(null);
            }
        }
Exemple #3
0
        /// <summary>
        ///   Acquire a request token from the given URI using the given
        ///   HTTP method.
        /// </summary>
        ///
        /// <remarks>
        ///   <para>
        ///     To use this method, first instantiate a new Oauth.Manager
        ///     object, then, optionally, set the callback param
        ///     (oauth["callback"]='oob'). Consult the Twitter documentation
        ///     for the meaning and usage of the callback parameter. After the
        ///     call returns, you should direct the user to open a browser
        ///     window to the authorization page for the OAuth-enabled
        ///     service. Or, you can automatically open that page yourself. Do
        ///     this with System.Diagnostics.Process.Start(), passing the URL
        ///     of the page.  If you're using Twitter, there should be one
        ///     query param: oauth_token with the value obtained from
        ///     oauth["token"]. See the example
        ///   </para>
        ///   <para>
        ///     According to the OAuth spec, you need to do this only ONCE per
        ///     application, the first time the application is run.  The
        ///     normal oauth workflow is: (1) get a request token, (2) use
        ///     that to acquire an access token (which requires explicit user
        ///     approval), then (3) using that access token, invoke protected
        ///     services. The first two steps need to be done only once, ever,
        ///     for each registered application. The third step can be
        ///     performed many times, over many invocations of the
        ///     application.
        ///   </para>
        ///   <para>
        ///     For Twitter, at least, you can cache the access tokens
        ///     indefinitely; Twitter says they never expire.  However, other
        ///     oauth services may not do the same. Also: the user may at any
        ///     time revoke his authorization for your app, in which case you
        ///     need to perform the first 2 steps again.
        ///   </para>
        /// </remarks>
        ///
        /// <seealso cref='AcquireAccessToken(string,string,string)'/>
        /// <seealso cref='AcquireAccessToken(string)'/>
        ///
        /// <example>
        ///   <para>
        ///     This example shows how to request an access token and key
        ///     from Twitter. It presumes you've already obtained a
        ///     consumer key and secret via app registration. Requesting
        ///     an access token is necessary only the first time you
        ///     contact the service. You can cache the access key and
        ///     token for subsequent runs, later.
        ///   </para>
        ///   <code>
        ///   // the URL to obtain a temporary "request token"
        ///   var rtUrl = "https://api.twitter.com/oauth/request_token";
        ///   var oauth = new OAuth.Manager();
        ///   // The consumer_{key,secret} are obtained via registration
        ///   oauth["client_id"] = "~~~client_id~~~~";
        ///   oauth["client_secret"] = "~~~client_secret~~~";
        ///   oauth.AcquireRequestToken(rtUrl, "POST");
        ///   // The request token is now available in oauth["token"]
        ///   // The next step is to pop the authorization approval dialog.
        ///   var authzUrl = "https://api.twitter.com/oauth/authorize?oauth_token=" + oauth["token"];
        ///   System.Diagnostics.Process.Start(authzUrl);
        ///   </code>
        /// </example>
        ///
        /// <param name="uri">The uri to the "request token" endpoint of
        /// the service that implements oauth.  For Twitter, this is
        /// "https://api.twitter.com/oauth/request_token".
        /// </param>
        ///
        /// <param name="method">The method you will use to send the
        /// message asking for a request token.  For Twitter, this
        /// should be "POST".
        /// </param>
        ///
        /// <returns>
        ///   a response object that contains the entire text of the response,
        ///   as well as extracted parameters. This method presumes the
        ///   response is query-param encoded. In other words,
        ///   poauth_token=foo&amp;something_else=bar.
        /// </returns>
        public OAuthResponse AcquireRequestToken(string uri, string method)
        {
            //NewRequest();
            var authzHeader = GetAuthorizationHeader(uri, method);

            // prepare the token request
            var request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(uri);

            request.Headers.Add("Authorization", authzHeader);
            request.Headers.Add("Ocp-Apim-Subscription-Key", _params["subscription-key"]);
            request.ContentType = "application/x-www-form-urlencoded";
            request.Method      = method;

            var campaign_id = Uri.EscapeDataString(_params["campaign_id"]);
            var username    = Uri.EscapeDataString(_params["username"]);
            var password    = Uri.EscapeDataString(_params["password"]);
            var postData    = $"grant_type=password&username={username}&password={password}&campaign_id={campaign_id}";

            byte[] byteArray = Encoding.UTF8.GetBytes(postData);
            request.ContentLength = byteArray.Length;
            using (var requestBody = request.GetRequestStream())
            {
                requestBody.Write(byteArray, 0, byteArray.Length);
            }

            using (var response = (System.Net.HttpWebResponse)request.GetResponse())
            {
                using (var reader = new System.IO.StreamReader(response.GetResponseStream()))
                {
                    var s = reader.ReadToEnd();
                    var r = new OAuthResponse(s);
                    this["access_token"] = r["access_token"];
                    this["token_type"]   = r["token_type"];
                    this["expires_in"]   = r["expires_in"];
                    return(r);
                }
            }
        }
Exemple #4
0
        /// <summary>
        ///   Acquire an access token, from the given URI, using the given
        ///   HTTP method.
        /// </summary>
        ///
        /// <remarks>
        ///   <para>
        ///     To use this method, you must first set the oauth_token to the value
        ///     of the request token.  Eg, oauth["token"] = "whatever".
        ///   </para>
        ///   <para>
        ///     According to the OAuth spec, you need to do this only ONCE per
        ///     application.  In other words, the first time the application
        ///     is run.  The normal oauth workflow is:  (1) get a request token,
        ///     (2) use that to acquire an access token (which requires explicit
        ///     user approval), then (3) using that access token, invoke
        ///     protected services.  The first two steps need to be done only
        ///     once per application.
        ///   </para>
        ///   <para>
        ///     For Twitter, at least, you can cache the access tokens
        ///     indefinitely; Twitter says they never expire.  However, other
        ///     oauth services may not do the same. Also: the user may at any
        ///     time revoke his authorization for your app, in which case you
        ///     need to perform the first 2 steps again.
        ///   </para>
        /// </remarks>
        ///
        /// <seealso cref='AcquireRequestToken'>
        ///
        /// <returns>
        ///   a response object that contains the entire text of the response,
        ///   as well as extracted parameters. This method presumes the
        ///   response is query-param encoded. In other words,
        ///   poauth_token=foo&something_else=bar.
        /// </returns>
        public OAuthResponse AcquireAccessToken(string uri, string method, string pin)
        {
            NewRequest();
            _params["verifier"] = pin;

            var authzHeader = GetAuthorizationHeader(uri, method);

            // prepare the token request
            var request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(uri);

            request.Headers.Add("Authorization", authzHeader);
            request.Method = method;

            using (var response = (System.Net.HttpWebResponse)request.GetResponse())
            {
                using (var reader = new System.IO.StreamReader(response.GetResponseStream()))
                {
                    var r = new OAuthResponse(reader.ReadToEnd());
                    this["token"]        = r["oauth_token"];
                    this["token_secret"] = r["oauth_token_secret"];
                    return(r);
                }
            }
        }
Exemple #5
0
        /// <summary>
        ///   Acquire a request token, from the given URI, using the given
        ///   HTTP method.
        /// </summary>
        ///
        /// <remarks>
        ///   <para>
        ///     To use this method, first instantiate a new Oauth.Manager object,
        ///     then set the callback param (oauth["callback"]='oob'). After the
        ///     call returns, you should direct the user to open a browser window
        ///     to the authorization page for the OAuth-enabled service. Or,
        ///     you can automatically open that page yourself. Do this with
        ///     System.Diagnostics.Process.Start(), passing the URL of the page.
        ///     There should be one query param: oauth_token with the value
        ///     obtained from oauth["token"].
        ///   </para>
        ///   <para>
        ///     According to the OAuth spec, you need to do this only ONCE per
        ///     application.  In other words, the first time the application
        ///     is run.  The normal oauth workflow is:  (1) get a request token,
        ///     (2) use that to acquire an access token (which requires explicit
        ///     user approval), then (3) using that access token, invoke
        ///     protected services.  The first two steps need to be done only
        ///     once per application.
        ///   </para>
        ///   <para>
        ///     For Twitter, at least, you can cache the access tokens
        ///     indefinitely; Twitter says they never expire.  However, other
        ///     oauth services may not do the same. Also: the user may at any
        ///     time revoke his authorization for your app, in which case you
        ///     need to perform the first 2 steps again.
        ///   </para>
        /// </remarks>
        ///
        /// <seealso cref='AcquireAccessToken'>
        ///
        ///
        /// <example>
        ///   <para>
        ///     This example shows how to request an access token and key
        ///     from Twitter. It presumes you've already obtained a
        ///     consumer key and secret via app registration. Requesting
        ///     an access token is necessary only the first time you
        ///     contact the service. You can cache the access key and
        ///     token for subsequent runs, later.
        ///   </para>
        ///   <code>
        ///   // the URL to obtain a temporary "request token"
        ///   var rtUrl = "https://api.twitter.com/oauth/request_token";
        ///   var oauth = new OAuth.Manager();
        ///   // The consumer_{key,secret} are obtained via registration
        ///   oauth["consumer_key"] = "~~~CONSUMER_KEY~~~~";
        ///   oauth["consumer_secret"] = "~~~CONSUMER_SECRET~~~";
        ///   oauth.AcquireRequestToken(rtUrl, "POST");
        ///   var authzUrl = "https://api.twitter.com/oauth/authorize?oauth_token=" + oauth["token"];
        ///   System.Diagnostics.Process.Start(authzUrl);
        ///   // instruct the user to type in the PIN from that browser window
        ///   var pin = "...";
        ///   var atUrl = "https://api.twitter.com/oauth/access_token";
        ///   oauth.AcquireAccessToken(atUrl, "POST", pin);
        ///
        ///   // now, update twitter status using that access token
        ///   var appUrl = "http://api.twitter.com/1/statuses/update.xml?status=Hello";
        ///   var authzHeader = oauth.GenerateAuthzHeader(appUrl, "POST");
        ///   var request = (HttpWebRequest)WebRequest.Create(appUrl);
        ///   request.Method = "POST";
        ///   request.PreAuthenticate = true;
        ///   request.AllowWriteStreamBuffering = true;
        ///   request.Headers.Add("Authorization", authzHeader);
        ///
        ///   using (var response = (HttpWebResponse)request.GetResponse())
        ///   {
        ///     if (response.StatusCode != HttpStatusCode.OK)
        ///       MessageBox.Show("There's been a problem trying to tweet:" +
        ///                       Environment.NewLine +
        ///                       response.StatusDescription);
        ///   }
        ///   </code>
        /// </example>
        ///
        /// <returns>
        ///   a response object that contains the entire text of the response,
        ///   as well as extracted parameters. This method presumes the
        ///   response is query-param encoded. In other words,
        ///   poauth_token=foo&something_else=bar.
        /// </returns>
        public OAuthResponse AcquireRequestToken(string uri, string method)
        {
            NewRequest();
            var authzHeader = GetAuthorizationHeader(uri, method);

            // prepare the token request
            var request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(uri);
            request.Headers.Add("Authorization", authzHeader);
            request.Method = method;

            using (var response = (System.Net.HttpWebResponse)request.GetResponse())
            {
                using (var reader = new System.IO.StreamReader(response.GetResponseStream()))
                {
                    var r = new OAuthResponse(reader.ReadToEnd());
                    this["token"] = r["oauth_token"];

                    // Sometimes the request_token URL gives us an access token,
                    // with no user interaction required. Eg, when prior approval
                    // has already been granted.
                    try
                    {
                        if (r["oauth_token_secret"] != null)
                            this["token_secret"] = r["oauth_token_secret"];
                    }
                    catch { }
                    return r;
                }
            }
        }
Exemple #6
0
        /// <summary>
        ///   Acquire an access token, from the given URI, using the given
        ///   HTTP method.
        /// </summary>
        ///
        /// <remarks>
        ///   <para>
        ///     To use this method, you must first set the oauth_token to the value
        ///     of the request token.  Eg, oauth["token"] = "whatever".
        ///   </para>
        ///   <para>
        ///     According to the OAuth spec, you need to do this only ONCE per
        ///     application.  In other words, the first time the application
        ///     is run.  The normal oauth workflow is:  (1) get a request token,
        ///     (2) use that to acquire an access token (which requires explicit
        ///     user approval), then (3) using that access token, invoke
        ///     protected services.  The first two steps need to be done only
        ///     once per application.
        ///   </para>
        ///   <para>
        ///     For Twitter, at least, you can cache the access tokens
        ///     indefinitely; Twitter says they never expire.  However, other
        ///     oauth services may not do the same. Also: the user may at any
        ///     time revoke his authorization for your app, in which case you
        ///     need to perform the first 2 steps again.
        ///   </para>
        /// </remarks>
        ///
        /// <seealso cref='AcquireRequestToken'>
        ///
        /// <returns>
        ///   a response object that contains the entire text of the response,
        ///   as well as extracted parameters. This method presumes the
        ///   response is query-param encoded. In other words,
        ///   poauth_token=foo&something_else=bar.
        /// </returns>
        public OAuthResponse AcquireAccessToken(string uri, string method, string pin)
        {
            NewRequest();
            _params["verifier"] = pin;

            var authzHeader = GetAuthorizationHeader(uri, method);

            // prepare the token request
            var request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(uri);
            request.Headers.Add("Authorization", authzHeader);
            request.Method = method;

            using (var response = (System.Net.HttpWebResponse)request.GetResponse())
            {
                using (var reader = new System.IO.StreamReader(response.GetResponseStream()))
                {
                    var r = new OAuthResponse(reader.ReadToEnd());
                    this["token"] = r["oauth_token"];
                    this["token_secret"] = r["oauth_token_secret"];
                    return r;
                }
            }
        }
Exemple #7
0
        /// <summary>
        ///   Acquire an access token, from the given URI, using the given
        ///   HTTP method.
        /// </summary>
        ///
        /// <remarks>
        ///   <para>
        ///     To use this method, you must first set the oauth_token to the value
        ///     of the request token.  Eg, oauth["token"] = "whatever".
        ///   </para>
        ///   <para>
        ///     According to the OAuth spec, you need to do this only ONCE per
        ///     application.  In other words, the first time the application
        ///     is run.  The normal oauth workflow is:  (1) get a request token,
        ///     (2) use that to acquire an access token (which requires explicit
        ///     user approval), then (3) using that access token, invoke
        ///     protected services.  The first two steps need to be done only
        ///     once per application.
        ///   </para>
        ///   <para>
        ///     For Twitter, at least, you can cache the access tokens
        ///     indefinitely; Twitter says they never expire.  However, other
        ///     oauth services may not do the same. Also: the user may at any
        ///     time revoke his authorization for your app, in which case you
        ///     need to perform the first 2 steps again.
        ///   </para>
        /// </remarks>
        ///
        /// <seealso cref='AcquireRequestToken()'/>
        ///
        /// <example>
        ///   <para>
        ///     This example shows how to request an access token and key
        ///     from Twitter. It presumes you've already obtained a
        ///     consumer key and secret via app registration. Requesting
        ///     an access token is necessary only the first time you
        ///     contact the service. You can cache the access key and
        ///     token for subsequent runs, later.
        ///   </para>
        ///   <code>
        ///   // the URL to obtain a temporary "request token"
        ///   var rtUrl = "https://api.twitter.com/oauth/request_token";
        ///   var oauth = new OAuth.Manager();
        ///   // The consumer_{key,secret} are obtained via registration
        ///   oauth["consumer_key"] = "~~~CONSUMER_KEY~~~~";
        ///   oauth["consumer_secret"] = "~~~CONSUMER_SECRET~~~";
        ///   oauth.AcquireRequestToken(rtUrl, "POST");
        ///   var authzUrl = "https://api.twitter.com/oauth/authorize?oauth_token=" + oauth["token"];
        ///   // Normally you'd want to pop this in a WebBrowser control.
        ///   // For the example only, we'll pop the URL in a separate browser.
        ///   System.Diagnostics.Process.Start(authzUrl);
        ///   // instruct the user to type in the PIN from that browser window
        ///   var pin = "...";
        ///   var atUrl = "https://api.twitter.com/oauth/access_token";
        ///   oauth.AcquireAccessToken(atUrl, "POST", pin);
        ///
        ///   // now, update twitter status using that access token
        ///   var appUrl = "http://api.twitter.com/1/statuses/update.xml?status=Hello";
        ///   var authzHeader = oauth.GenerateAuthzHeader(appUrl, "POST");
        ///   var request = (HttpWebRequest)WebRequest.Create(appUrl);
        ///   request.Method = "POST";
        ///   request.PreAuthenticate = true;
        ///   request.AllowWriteStreamBuffering = true;
        ///   request.Headers.Add("Authorization", authzHeader);
        ///
        ///   using (var response = (HttpWebResponse)request.GetResponse())
        ///   {
        ///     if (response.StatusCode != HttpStatusCode.OK)
        ///       MessageBox.Show("There's been a problem trying to tweet:" +
        ///                       Environment.NewLine +
        ///                       response.StatusDescription);
        ///   }
        ///   </code>
        /// </example>
        ///
        /// <param name="uri">The uri to the "access token" endpoint of
        /// the service that implements oauth.  For Twitter, this is
        /// "https://api.twitter.com/oauth/access_token".
        /// </param>
        ///
        /// <param name="method">The method you will use to send the
        /// message asking for an access token.  For Twitter, this
        /// should be "POST".
        /// </param>
        ///
        /// <param name="pin">The PIN returned by the "Application approval" page
        /// shown by Twitter.  It's a string of numeric digits, 7 or so digits in
        /// length.
        /// </param>
        ///
        /// <returns>
        ///   a response object that contains the entire text of the response,
        ///   as well as extracted parameters. This method presumes the
        ///   response is query-param encoded. In other words,
        ///   oauth_token=foo&amp;something_else=bar.
        /// </returns>
        public OAuthResponse AcquireAccessToken(string uri, string method, string pin)
        {
            Tracing.Trace("AcquireAccessToken.");
            NewRequest();
            _params.Remove("callback"); // no longer needed
            _params["verifier"] = pin;

            var authzHeader = GetAuthorizationHeader(uri, method);

            try
            {
                // prepare the token request
                var request = (System.Net.HttpWebRequest) System.Net.WebRequest.Create(uri);
                request.Headers.Add("Authorization", authzHeader);
                request.Method = method;

                using (var response = (System.Net.HttpWebResponse)request.GetResponse())
                {
                    using (var reader = new System.IO.StreamReader(response.GetResponseStream()))
                    {
                        var s = reader.ReadToEnd();
                        Tracing.Trace("resp: {0}", s);
                        var r = new OAuthResponse(s);
                        this["token"] = r["oauth_token"];
                        this["token_secret"] = r["oauth_token_secret"];
                        _params.Remove("verifier"); // not needed any longer
                        return r;
                    }
                }
            }
            catch (Exception ex1)
            {
                Tracing.Trace("Exception: {0}", ex1.ToString());
                _params.Remove("verifier"); // not needed any longer
                return null;
            }
        }