我正在尝试创建一个基于 .NET 的客户端应用程序(在 WPF 中 - 尽管目前我只是将其作为控制台应用程序)以与支持 OAuth 的应用程序集成,特别是 Mendeley (http://dev.mendeley.com),它显然使用了 3 足 OAuth。

这是我第一次使用 OAuth,上手时遇到很多困难。

到目前为止,我已经尝试过:

第一个(DotNetOpenAuth)似乎可以做我需要的事情,如果我花了几个小时试图弄清楚如何做。

我从 Mendeley 获得了消费者密钥和秘密,并且通过 DotNetOpenAuth,我成功地启动了一个浏览器,其中包含 Mendeley 页面,为用户提供了进入应用程序的验证码。

我非常愿意承认我不知道从哪里开始(尽管似乎有一个相当陡峭的学习曲线) - 如果有人能指出我正确的方向,我将不胜感激!

答案

我同意你的看法。

不需要这么复杂。

我不是 OAuth 方面的专家,但我已经制作了一个 OAuth 客户端管理器类,我成功地将其与 Twitter 和 TwitPic 一起使用。Oauth.cs

回顾一下,在 OAuth 1.0a 中……有点有趣,有一个特殊的名称,它看起来像一个"标准",但据我所知,唯一实现"OAuth 1.0a"的服务是 Twitter。足够的对于桌面应用程序这是:

  1. 您,应用程序的开发者,注册应用程序并获得"消费者密钥"和"消费者秘密"。详细分析了为什么这个模型不是最好的,但正如他们所说,就是这样

  2. 您的应用程序运行。

    • 请求"请求令牌"。
    • 弹出一个网页,将该请求令牌作为查询参数传递。
    • 用户登录 Twitter 网页,并授予或拒绝访问权限。
    • 出现响应 html 页面。
    • 用户现在需要将该引脚剪切/粘贴到 Windows 表单框中,然后单击"下一步"或类似的操作。
    • 然后,桌面应用程序会对"访问令牌"发出经过 oauth 身份验证的请求。
    • 桌面应用程序接收"访问令牌"和"访问密钥"。

在批准舞蹈之后,桌面应用程序可以仅使用用户特定的"访问令牌"和"访问秘密"(以及应用程序特定的"消费者密钥"和"消费者秘密")代表用户执行经过身份验证的请求


如果您不聪明,UI 流可以在某种程度上反映多步骤 OAuth 消息流。

使用 WebBrowser 控件,并在桌面应用程序中打开授权网页。

像这样:
alt text


如果您已经对 UI 进行了排序,剩下的唯一挑战就是生成 oauth 签名的请求。

请求令牌的示例代码:

var oauth = new OAuth.Manager();
// the URL to obtain a temporary "request token"
var rtUrl = "https://api.twitter.com/oauth/request_token";
oauth["consumer_key"] = MY_APP_SPECIFIC_KEY;
oauth["consumer_secret"] = MY_APP_SPECIFIC_SECRET;    
oauth.AcquireRequestToken(rtUrl, "POST");

THAT’S IThttps://api.twitter.com/oauth/request_token"。oauth 规范表示,您需要以某种方式(url 编码并由&符号连接)打包 oauth 参数集(token、token_secret、nonce、timestamp、consumer_key、version 和callback),并以OAuth 管理器类会自动为您完成此操作。 它生成过的nonce和时间戳和版本和签名自动 - 您的应用程序不需要关心或了解这些东西。

好吧,然后呢?https://api.twitter.com/oauth/authorize?oauth_token=" 并附加了 oauth_token。在代码中执行此操作,如下所示:

var url = SERVICE_SPECIFIC_AUTHORIZE_URL_STUB + oauth["token"];
webBrowser1.Url = new Uri(url);

(如果您在外部浏览器中执行此操作,则可以使用System.Diagnostics.Process.Start(url).)

设置 Url 属性会使 WebBrowser 控件自动导航到该页面。

当用户单击"允许"按钮将加载一个新页面。

var divMarker = "<div id=\"oauth_pin\">"; // the div for twitter's oauth pin
var index = webBrowser1.DocumentText.LastIndexOf(divMarker) + divMarker.Length;
var snip = web1.DocumentText.Substring(index);
var pin = RE.Regex.Replace(snip,"(?s)[^0-9]*([0-9]+).*", "$1").Trim();

这是一些 HTML 屏幕抓取。

获取 PIN 码后,您不再需要网络浏览器,因此:

webBrowser1.Visible = false; // all done with the web UI

…您可能还想对其调用 Dispose() 。

下一步是通过与该 pin 一起发送另一条 HTTP 消息来获取访问令牌。

oauth.AcquireAccessToken(URL_ACCESS_TOKEN,
                         "POST",
                         pin);

对于 Twitter,该 URL 是"https://api.twitter.com/oauth/access_token"。

现在您拥有访问令牌,并且可以在签名的 HTTP 请求中使用它们。

var authzHeader = oauth.GenerateAuthzHeader(url, "POST");

…在哪里url是资源端点。http://api.twitter.com/1/statuses/update.xml?status=Hello"。

然后将该字符串设置到名为的 HTTP 标头中Authorization

要与第三方服务(例如 TwitPic)交互,您需要构建一个稍微不一样OAuth 标头,如下所示:

var authzHeader = oauth.GenerateCredsHeader(URL_VERIFY_CREDS,
                                            "GET",
                                            AUTHENTICATION_REALM);

对于 Twitter,验证信用 url 和领域的值为"https://api.twitter.com/1/account/verify_credentials.json", 和 “http://api.twitter.com/” 分别。

…然后把 HTTP 标头中的授权字符串称为X-Verify-Credentials-Authorization

就是这样。

总而言之,更新 Twitter 状态的代码可能如下所示:

// 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"];
// here, should use a WebBrowser control. 
System.Diagnostics.Process.Start(authzUrl);  // example only!
// 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);
}

OAuth 1.0a 在幕后有点复杂,但使用它并不需要如此。

在后续运行中,当您已经拥有访问令牌和密钥时,您可以像这样实例化 OAuth.Manager:

var oauth = new OAuth.Manager();
oauth["consumer_key"] = CONSUMER_KEY;
oauth["consumer_secret"] = CONSUMER_SECRET;
oauth["token"] = your_stored_access_token;
oauth["token_secret"] = your_stored_access_secret;

…然后如上所述生成授权标头。

// 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);
}

您可以下载一个包含OAuth的DLL。在线查看帮助文件

查看使用此管理器的 Windows 窗体示例这里


工作示例

下载工作示例使用此处描述的类和技术的命令行工具:

来自: stackoverflow.com