Eventually I used a WebBrowser object in WinForms to solve this issue. Here's my code:
public Authenticate()
{
InitializeComponent();
//Request token
Client.BaseUrl = Server_url;
Client.Authenticator = OAuth1Authenticator.ForRequestToken(Consumer_key, Consumer_secret);
RestRequest request = new RestRequest("api/auth/request_token", Method.GET);
//request response
var response = Client.Execute(request);
//pull out the google url out of the response (which is a HTML page)
int index = response.Content.IndexOf("/api/auth/request_token_callback/google/") + "/api/auth/request_token_callback/google/".Length;
string key = response.Content.Substring(index, 10);
if (response.StatusDescription.Equals("OK"))
{
var url = response.ResponseUri.AbsoluteUri;
webBrowser.Navigate(new Uri(url));
}
else
throw new Exception();
}
And when the user finishes to authenticate through Google/Facebook/Email, I can pull out his oauth_token and oauth_token_secret using webBrowser.Url:
string source = webBrowser.Url.ToString();
var qs = HttpUtility.ParseQueryString(source);
var oauth_token_secret = HttpUtility.ParseQueryString(source).Get(0);
var oauth_token = qs["oauth_token"];
Client.BaseUrl = Server_url;
Client.Authenticator = OAuth1Authenticator.ForAccessToken(Consumer_key, Consumer_secret, oauth_token, oauth_token_secret);
By the way, there's a bug with HttpUtility.ParseQueryString(source). see this post for a solution (that's also implemented here)