与OAuth的认证在.NET [英] OAuth with Verification in .NET

查看:266
本文介绍了与OAuth的认证在.NET的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建一个基于.NET的客户端应用程序(在WPF中 - 虽然暂时我只是在做它作为一个控制台应用程序)与支持OAuth的应用程序集成,具体的Mendeley(HTTP: //dev.mendeley.com),这显然使用了3条腿OAuth的。

I'm trying to create a .NET-based client app (in WPF - although for the time being I'm just doing it as a console app) to integrate with an OAuth-enabled application, specifically Mendeley (http://dev.mendeley.com), which apparently uses 3-legged OAuth.

这是我第一次使用OAuth,和我有很多困难开始使用它。我已经发现了几个.NET的OAuth库或佣工,但他们似乎比我想我需要更加复杂。所有我想要做的就是能够发出REST请求到的Mendeley API,并得到响应回来了!

This is my first time using OAuth, and I'm having a lot of difficulty getting started with it. I've found several .NET OAuth libraries or helpers, but they seem to be more complicated than I think I need. All I want to do is be able to issue REST requests to the Mendeley API and get responses back!

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

So far, I've tried:

  • DotNetOpenAuth
  • <一个href="http://github.com/bitter$c$cr/DevDefined.OAuth">http://github.com/bitter$c$cr/DevDefined.OAuth
  • <一个href="http://oauth.google$c$c.com/svn/$c$c/csharp/">http://oauth.google$c$c.com/svn/$c$c/csharp/
  • DotNetOpenAuth
  • http://github.com/bittercoder/DevDefined.OAuth
  • http://oauth.googlecode.com/svn/code/csharp/

第一(DotNetOpenAuth)似乎是它可能做什么,我需要的,如果我花了几个小时,试图找出如何。第二和第三,尽我可以告诉,不支持验证codeS的的Mendeley正在发回 - 尽管我可能是错的:)

The first (DotNetOpenAuth) seems like it could possibly do what I needed if I spent hours and hours trying to work out how. The second and third, as best I can tell, don't support the verification codes that Mendeley is sending back -- although I could be wrong about this :)

我有一个消费者密钥和秘密从的Mendeley,并与DotNetOpenAuth我设法用的Mendeley页面提供验证code用户进入应用程序启动一个浏览器。然而,在这一点上,我迷路了,不能工作,如何合理地提供给应用程序。

I've got a consumer key and secret from Mendeley, and with DotNetOpenAuth I managed to get a browser launched with the Mendeley page providing a verification code for the user to enter into the application. However, at this point I got lost and couldn't work out how to sensibly provide that back to the application.

我很愿意承认,我不知道从哪里开始这个(尽管它好像有一个相当陡峭的学习曲线) - 如果有人能在正确的方向指向我,我会把AP preciate它!

I'm very willing to admit that I have no idea where to start with this (although it seems like there's quite a steep learning curve) - if anyone can point me in the right direction I'd appreciate it!

推荐答案

我同意你的看法。可用于.NET应用程序的开放源代码的OAuth支持类是很难理解的,过于复杂(有多少方法,通过DotNetOpenAuth暴露?),设计不佳(看与在OAuthBase.cs模块10字符串参数方法从谷歌链接您提供 - 有没有状态管理的话),或以其他方式不能令人满意。

I agree with you. The open-source OAuth support classes available for .NET apps are hard to understand, overly complicated (how many methods are exposed by DotNetOpenAuth?), poorly designed (look at the methods with 10 string parameters in the OAuthBase.cs module from that google link you provided - there's no state management at all), or otherwise unsatisfactory.

它并不需要是这种复杂。

It doesn't need to be this complicated.

我不是OAuth的专家,但我产生了OAuth的客户端管理器类,我成功地使用与Twitter和TwitPic。这是相对简单的使用。它是开源的,可以在这里找到:<一href="http://cropperplugins.$c$cplex.com/SourceControl/changeset/view/72088#1710422">Oauth.cs

I'm not an expert on OAuth, but I have produced an OAuth client-side manager class, that I use successfully with Twitter and TwitPic. It's relatively simple to use. It's open source and available here: Oauth.cs

有关的审查,在OAuth的1.0A ...有点滑稽,有一个特别的名字,它看起来像一个标准,但据我知道,实现OAuth的1.0A的唯一服务就是微博。我想这是标准的足够的。好吧,反正在1.0A的OAuth的方式,它的工作原理的的桌面应用程序的是这样的:

For review, in OAuth 1.0a...kinda funny, there's a special name and it looks like a "standard" but as far as I know the only service that implements "OAuth 1.0a" is Twitter. I guess that's standard enough. ok, anyway in OAuth 1.0a, the way it works for desktop apps is this:

  1. 您的应用程序的开发者,注册应用程序,并获得了消费者键和消费者的秘密。在Arstechnica,有<一href="http://arstechnica.com/security/guides/2010/09/twitter-a-case-study-on-how-to-do-oauth-wrong.ars/3">a写得很好的,为什么这种模式是不是最好的的分析,但正如他们所说,这是它是什么的。

  1. You, the developer of the app, register the app and get a "consumer key" and "consumer secret". On Arstechnica, there's a well written analysis of why this model isn't the best, but as they say, it is what it is.

您的应用程序运行。第一次运行,它需要得到用户明确地予以批准的应用程序,使OAuth的认证的REST请求,Twitter和它的姊妹服务(如TwitPic)。要做到这一点,你必须经过审批过程中,涉及明确批准的用户。这种情况只有在第一次应用程序运行。像这样的:

Your app runs. The first time it runs, it needs to get the user to explicitly grant approval for the app to make oauth-authenticated REST requests to Twitter and its sister services (like TwitPic). To do this you must go through an approval process, involving explicit approval by the user. This happens only the first time the app runs. Like this:

  • 申请请求令牌。阿卡临时令牌。
  • 在弹出的网页,通过该请求令牌作为查询参数。此网页presents UI给用户,问:你要授予访问该应用程序吗?
  • 在对Twitter的网页的用户登录,并授予或拒绝访问。
  • 出现在响应HTML页面。如果用户已授权访问,有一个48磅的字体显示的PIN
  • 用户现在需要剪切/粘贴销插入Windows窗体复选框,然后单击下一步或类似的东西。
  • 在桌面应用程序,然后做了一个访问令牌OAuth的认证请求。另一个REST请求。
  • 在桌面应用程序收到访问令牌和秘密访问。

在批准的舞蹈,桌面应用程序可以只使用用户特定的访问令牌和获得的秘密(以及应用程序的特定消费者键和消费者的秘密)做代表认证的请求用户的Twitter。这些不会过期,但如果用户取消授权的应用程序,或者如果Twitter因某种原因取消授权您的应用程序,或者如果你失去了你的访问令牌和/或秘密,你需要再次进行审批的舞蹈。

After the approval dance, the desktop app can just use the user-specific "access token" and "access secret" (along with the app-specific "consumer key" and "consumer secret") to do authenticated requests on behalf of the user to Twitter. These don't expire, although if the user de-authorizes the app, or if Twitter for some reason de-authorizes your app, or if you lose your access token and/or secret, you'd need to do the approval dance again.

如果你不聪明,在UI流量可排序的反映多步OAuth的消息流。有一种更好的方式。

If you're not clever, the UI flow can sort of mirror the multi-step OAuth message flow. There is a better way.

使用WebBrowser控件,并在桌面上的应用程序打开授权网页。当用户点击允许,抓住从WebBrowser控件响应文本,自动提取码,然后获得访问令牌。你送5或6的HTTP请求,但用户需要看到的只是一个允许/拒绝对话。简单的。

Use a WebBrowser control, and open the authorize web page within the desktop app. When the user clicks "Allow", grab the response text from that WebBrowser control, extract the PIN automatically, then get the access tokens. You send 5 or 6 HTTP requests but the user needs to see only a single Allow/Deny dialog. Simple.

所示:

Like this:

如果你有UI排序,剩下的唯一挑战是生产OAuth的签名请求。这种旅行了很多人,因为OAuth的签名要求,也是一种特别。这就是简化OAuth的管理类完成。

If you've got the UI sorted, the only challenge that remains is to produce oauth-signed requests. This trips up lots of people because the oauth signing requirements are sort of particular. That's what the simplified OAuth Manager class does.

例如code请求令牌:

Example code to request a token:

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");

就是这样。简单。正如你可以从code看,顺便去OAuth的参数是通过基于字符串的索引,就像一本字典的东西。该AcquireRequestToken方法发送的OAuth签名请求授予请求令牌,又名临时令牌服务的URL。对于微博,这个URL是https://api.twitter.com/oauth/request_token。 OAuth规范说,你需要收拾组的OAuth参数(令牌,token_secret,现时,时间戳,CONSUMER_KEY,版本和回调),以一定的方式(URL-CN codeD和&符号连接),以及在一个字典顺序-排序顺序,生成在该结果的签名,然后收拾那些相同的参数随签名,存储在新oauth_signature参数,以不同的方式(用逗号接合)。 基于OAuth的认证管理器类将自动为您完成此的它产生的随机数和时间戳和版本的和签名的自动 - 您的应用程序并不需要关心和注意的东西。只需设置OAuth的参数值,并做一个简单的方法调用。经理级发出请求并解析为您的响应。

THAT'S IT. Simple. As you can see from the code, the way to get to oauth parameters is via a string-based indexer, something like a dictionary. The AcquireRequestToken method sends an oauth-signed request to the URL of the service that grants request tokens, aka temporary tokens. For Twitter, this URL is "https://api.twitter.com/oauth/request_token". The oauth spec says you need to pack up the set of oauth parameters (token, token_secret, nonce, timestamp, consumer_key, version, and callback), in a certain way (url-encoded and joined by ampersands), and in a lexicographically-sorted order, generate a signature on that result, then pack up those same parameters along with the signature, stored in the new oauth_signature parameter, in a different way (joined by commas). The OAuth manager class does this for you automatically. It generates nonces and timestamps and versions and signatures automatically - your app doesn't need to care or be aware of that stuff. Just set the oauth parameter values and make a simple method call. the manager class sends out the request and parses the response for you.

好了,然后呢?一旦你的请求令牌,你弹出的网页浏览器的用户界面中,用户将明确地予以批准。如果你这样做是正确的,你会在一个嵌入式浏览器弹出这一点。对于微博的网址,这是https://api.twitter.com/oauth/authorize?oauth_token=与追加oauth_token。为此,在code像这样:

Ok, then what? Once you get the request token, you pop the web browser UI in which the user will explicitly grant approval. If you do it right, you'll pop this in an embedded browser. For Twitter, the URL for this is "https://api.twitter.com/oauth/authorize?oauth_token=" with the oauth_token appended. Do this in code like so:

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

(如果你在外部浏览器做这个,你会使用 System.Diagnostics.Process.Start(URL)

(If you were doing this in an external browser you'd use System.Diagnostics.Process.Start(url).)

设置URL属性将导致WebBrowser控件自动导航到该页面。

Setting the Url property causes the WebBrowser control to navigate to that page automatically.

当用户点击允许按钮一个新的页面将被加载。这是一个HTML表单,它的工作原理相同,在一个完整的浏览器。在您的code,注册的处理程序WebBrowser控件的DocumentedCompleted事件,并在该处理程序,抢针:

When the user clicks the "Allow" button a new page will be loaded. It's an HTML form and it works the same as in a full browser. In your code, register a handler for the DocumentedCompleted event of the WebBrowser control, and in that handler, grab the pin:

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屏幕抓取。

That's a bit of HTML screen scraping.

抓住针后,您不必对网页浏览器了,所以:

After grabbing the pin, you don't need the web browser any more, so:

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

...你可能要调用Dispose()上它。

...and you might want to call Dispose() on it as well.

下一步是获得访问令牌,通过发送另一个HTTP消息连同针。这又是一个签署的OAuth呼吁,与OAuth的顺序和格式我上面建造。但是,再一次,这是与OAuth.Manager类很简单:

The next step is getting the access token, by sending another HTTP message along with that pin. This is another signed oauth call, constructed with the oauth ordering and formatting I described above. But once again this is really simple with the OAuth.Manager class:

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

有关的Twitter,该网址是https://api.twitter.com/oauth/access_token。

For Twitter, that URL is "https://api.twitter.com/oauth/access_token".

现在你有访问令牌,你可以使用它们签署的HTTP请求。像这样的:

Now you have access tokens, and you can use them in signed HTTP requests. Like this:

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

...其中,网​​址是资源的端点。要更新用户的状态,这将是http://api.twitter.com/1/statuses/update.xml?status=Hello。

...where url is the resource endpoint. To update the user's status, it would be "http://api.twitter.com/1/statuses/update.xml?status=Hello".

然后设置该字符串到一个名为授权的HTTP头

Then set that string into the HTTP Header named Authorization.

要与第三方服务进行交互,比如TwitPic,你需要构造一个的略有不同的OAuth的头,像这样的:

To interact with third-party services, like TwitPic, you need to construct a slightly different OAuth header, like this:

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

有关Twitter的,为验证creds URL和域的值是https://api.twitter.com/1/account/verify_credentials.json和http://api.twitter.com/分别。

For Twitter, the values for the verify creds url and realm are "https://api.twitter.com/1/account/verify_credentials.json", and "http://api.twitter.com/" respectively.

...并把的HTTP头中所谓的 X-验证-凭证,授权授权字符串。然后发送给您的服务,像TwitPic,以及任何要求你发送。

...and put that authorization string in an HTTP header called X-Verify-Credentials-Authorization. Then send that to your service, like TwitPic, along with whatever request you're sending.

就是这样。

总之,在code更新Twitter的状态可能是这样的:

All together, the code to update twitter status might be something like this:

// 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处理生成传出的OAuth请求,并且在响应的OAuth内容的接收和处理。当Request_token请求给你一个oauth_token,您的应用程序并不需要存储。该Oauth.Manager是足够聪明,做这件事。同样,当access_token要求回来访问令牌和秘密,你并不需要显式地存储这些。该OAuth.Manager为你处理的状态。

OAuth 1.0a is sort of complicated under the covers, but using it doesn't need to be. The OAuth.Manager handles the generation of outgoing oauth requests, and the receiving and processing of oauth content in the responses. When the Request_token request gives you an oauth_token, your app doesn't need to store it. The Oauth.Manager is smart enough to do that automatically. Likewise when the access_token request gets back an access token and secret, you don't need to explicitly store those. The OAuth.Manager handles that state for you.

在随后的运行中,当你已经拥有的访问令牌和秘密,你可以实例化OAuth.Manager是这样的:

In subsequent runs, when you already have the access token and secret, you can instantiate the OAuth.Manager like this:

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;

...然后生成授权头如上。

...and then generate authorization headers as above.

// 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.Manager类这里的DLL。也有在下载一个帮助文件。或者你可以查看帮助文件在线

You can download a DLL containing the OAuth.Manager class here. There is also a helpfile in that download. Or you can view the helpfile online.

请参阅Windows窗体使用该经理这里一个例子。

See an example of a Windows Form that uses this manager here.

下载的使用这里描述的类和方法的命令行工具的工作示例

Download a working example of a command-line tool that uses the class and technique described here:

这篇关于与OAuth的认证在.NET的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆