我正在尝试创建一个基于 .NET 的客户端应用程序(在 WPF 中 - 尽管目前我只是将其作为控制台应用程序)以与支持 OAuth 的应用程序集成,特别是 Mendeley (http://dev.mendeley.com),它显然使用了 3 足 OAuth。
这是我第一次使用 OAuth,上手时遇到很多困难。
到目前为止,我已经尝试过:
- DotNetOpenAuth
- http://github.com/bittercoder/DevDefined.OAuth
- http://oauth.googlecode.com/svn/code/csharp/
第一个(DotNetOpenAuth)似乎可以做我需要的事情,如果我花了几个小时试图弄清楚如何做。
我从 Mendeley 获得了消费者密钥和秘密,并且通过 DotNetOpenAuth,我成功地启动了一个浏览器,其中包含 Mendeley 页面,为用户提供了进入应用程序的验证码。
我非常愿意承认我不知道从哪里开始(尽管似乎有一个相当陡峭的学习曲线) - 如果有人能指出我正确的方向,我将不胜感激!
答案
我同意你的看法。
不需要这么复杂。
我不是 OAuth 方面的专家,但我已经制作了一个 OAuth 客户端管理器类,我成功地将其与 Twitter 和 TwitPic 一起使用。Oauth.cs
回顾一下,在 OAuth 1.0a 中……有点有趣,有一个特殊的名称,它看起来像一个"标准",但据我所知,唯一实现"OAuth 1.0a"的服务是 Twitter。足够的 。对于桌面应用程序这是:
您,应用程序的开发者,注册应用程序并获得"消费者密钥"和"消费者秘密"。详细分析了为什么这个模型不是最好的,但正如他们所说,就是这样。
您的应用程序运行。
- 请求"请求令牌"。
- 弹出一个网页,将该请求令牌作为查询参数传递。
- 用户登录 Twitter 网页,并授予或拒绝访问权限。
- 出现响应 html 页面。
- 用户现在需要将该引脚剪切/粘贴到 Windows 表单框中,然后单击"下一步"或类似的操作。
- 然后,桌面应用程序会对"访问令牌"发出经过 oauth 身份验证的请求。
- 桌面应用程序接收"访问令牌"和"访问密钥"。
在批准舞蹈之后,桌面应用程序可以仅使用用户特定的"访问令牌"和"访问秘密"(以及应用程序特定的"消费者密钥"和"消费者秘密")代表用户执行经过身份验证的请求
如果您不聪明,UI 流可以在某种程度上反映多步骤 OAuth 消息流。
使用 WebBrowser 控件,并在桌面应用程序中打开授权网页。
像这样:
如果您已经对 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 IT 。https://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 窗体示例这里。
工作示例
下载工作示例使用此处描述的类和技术的命令行工具: