gpt4 book ai didi

.net - .NET 中带验证的 OAuth

转载 作者:行者123 更新时间:2023-12-03 04:48:34 25 4
gpt4 key购买 nike

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

这是我第一次使用 OAuth,我在开始使用它时遇到了很多困难。我发现了几个 .NET OAuth 库或助手,但它们似乎比我认为的需要更复杂。我想要做的就是能够向 Mendeley API 发出 REST 请求并得到响应!

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

  • DotNetOpenAuth
  • http://github.com/bittercoder/DevDefined.OAuth
  • http://oauth.googlecode.com/svn/code/csharp/

  • 第一个(DotNetOpenAuth)似乎可以做我需要的事情,如果我花了几个小时试图弄清楚如何做。第二个和第三个,据我所知,不支持 Mendeley 发回的验证码——尽管我可能错了:)

    我从 Mendeley 那里获得了一个消费者 key 和 secret ,并且通过 DotNetOpenAuth 我设法启动了一个浏览器,Mendeley 页面提供了一个验证码供用户进入应用程序。但是,此时我迷路了,无法弄清楚如何明智地将其提供给应用程序。

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

    最佳答案

    我同意你的看法。 .NET 应用程序可用的开源 OAuth 支持类难以理解,过于复杂(DotNetOpenAuth 公开了多少方法?),设计不佳(查看来自该 google 的 OAuthBase.cs 模块中具有 10 个字符串参数的方法您提供的链接 - 根本没有状态管理),或者不满意。

    没必要这么复杂。

    我不是 OAuth 的专家,但我制作了一个 OAuth 客户端管理器类,我成功地将它用于 Twitter 和 TwitPic。使用起来相对简单。它是开源的,可在此处获得:Oauth.cs

    回顾一下,在 OAuth 1.0a 中......有点有趣,有一个特殊的名称,它看起来像一个“标准”,但据我所知,实现“OAuth 1.0a”的唯一服务是 Twitter。我想这已经足够标准了。好的,无论如何在 OAuth 1.0a 中,它对桌面应用程序的工作方式是这样的:

  • 您,应用程序的开发者,注册应用程序并获得“消费者 key ”和“消费者 secret ”。在 Arstechnica 上,有 a well written analysis of why this model isn't the best ,但正如他们所说,事实就是如此。
  • 您的应用程序运行。第一次运行时,它需要让用户明确批准应用程序向 Twitter 及其姊妹服务(如 TwitPic)发出 oauth 身份验证的 REST 请求。为此,您必须经过审批流程,包括用户的明确审批。这仅在应用程序第一次运行时发生。像这样:
  • 请求“请求 token ”。又名临时 token 。
  • 弹出一个网页,将该请求 token 作为查询参数传递。此网页向用户展示 UI,询问“您想授予对该应用程序的访问权限吗?”
  • 用户登录 Twitter 网页,并授予或拒绝访问权限。
  • 出现响应 html 页面。如果用户已授予访问权限,则会以 48 磅字体显示 PIN
  • 用户现在需要将该图钉剪切/粘贴到 Windows 表单框中,然后单击“下一步”或类似内容。
  • 然后桌面应用程序对“访问 token ”执行 oauth 身份验证请求。另一个 REST 请求。
  • 桌面应用程序接收“访问 token ”和“访问 secret ”。

  • 在批准舞蹈之后,桌面应用程序可以只使用用户特定的“访问 token ”和“访问 key ”(以及应用程序特定的“消费者 key ”和“消费者 secret ”)代表用户执行经过身份验证的请求到推特。这些不会过期,但如果用户取消对应用程序的授权,或者如果 Twitter 出于某种原因取消对您的应用程序的授权,或者如果您丢失了访问 token 和/或 secret ,则您需要再次进行审批.

    如果您不聪明,UI 流可以在某种程度上反射(reflect)多步骤 OAuth 消息流。有更好的方法。

    使用 WebBrowser 控件,并在桌面应用程序中打开授权网页。当用户单击“允许”时,从该 WebBrowser 控件中获取响应文本,自动提取 PIN,然后获取访问 token 。您发送 5 或 6 个 HTTP 请求,但用户只需要看到一个允许/拒绝对话框。简单。

    像这样:
    alt text

    如果您对 UI 进行了排序,剩下的唯一挑战就是生成 oauth 签名的请求。由于 oauth 签名要求有点特殊,这会让很多人感到困惑。这就是简化的 OAuth 管理器类所做的。

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

    就是这样 .简单。从代码中可以看出,获取 oauth 参数的方法是通过基于字符串的索引器,类似于字典。 AcquireRequestToken 方法向授予请求 token (即临时 token )的服务的 URL 发送 oauth 签名的请求。对于 Twitter,这个 URL 是“ https://api.twitter.com/oauth/request_token”。 oauth 规范说你需要打包一组 oauth 参数(token、token_secret、nonce、timestamp、consumer_key、version 和回调),以某种方式(url 编码并用 & 符号连接),并按字典顺序 -排序顺序,在该结果上生成一个签名,然后将这些相同的参数与签名一起打包,以不同的方式(用逗号连接)存储在新的 oauth_signature 参数中。 OAuth 管理器类会自动为您执行此操作。它会自动生成随机数和时间戳以及版本和签名 - 您的应用程序不需要关心或知道这些东西。只需设置 oauth 参数值并进行简单的方法调用。 manager 类发出请求并为您解析响应。

    好的,然后呢?获得请求 token 后,您会弹出 Web 浏览器 UI,用户将在其中明确授予批准。如果你做对了,你会在嵌入式浏览器中弹出它。对于 Twitter,它的 URL 是“ 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 控件自动导航到该页面。

    当用户单击“允许”按钮时,将加载一个新页面。它是一个 HTML 表单,它的工作方式与在完整浏览器中的工作方式相同。在您的代码中,为 WebBrowser 控件的 DocumentedCompleted 事件注册一个处理程序,并在该处理程序中获取 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 屏幕抓取。

    捕获大头针后,您不再需要网络浏览器,因此:
    webBrowser1.Visible = false; // all done with the web UI

    ...您可能还想对它调用 Dispose()。

    下一步是通过发送另一个 HTTP 消息以及该 pin 来获取访问 token 。这是另一个签名的 oauth 调用,使用我上面描述的 oauth 排序和格式构建。但是再一次,这对于 OAuth.Manager 类来说非常简单:
    oauth.AcquireAccessToken(URL_ACCESS_TOKEN,
    "POST",
    pin);

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

    现在您有了访问 token ,并且可以在签名的 HTTP 请求中使用它们。像这样:
    var authzHeader = oauth.GenerateAuthzHeader(url, "POST");

    ...哪里 url是资源端点。要更新用户的状态,它将是“ http://api.twitter.com/1/statuses/update.xml?status=Hello”。

    然后将该字符串设置到名为 的 HTTP header 中授权 .

    要与第三方服务(如 TwitPic)交互,您需要构造一个略有不同的 OAuth header ,如下所示:
    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 header 中X-Verify-Credentials-Authorization .然后将它连同您发送的任何请求一起发送到您的服务,例如 TwitPic。

    就是这样。

    总之,更新 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 处理传出 oauth 请求的生成,以及响应中 oauth 内容的接收和处理。当 Request_token 请求为您提供 oauth_token 时,您的应用程序不需要存储它。 Oauth.Manager 足够智能,可以自动执行此操作。同样,当 access_token 请求取回访问 token 和 secret 时,您不需要显式存储它们。 OAuth.Manager 为您处理该状态。

    在后续运行中,当您已经拥有访问 token 和密码时,您可以像这样实例化 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;

    ...然后如上所述生成授权 header 。
    // 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);
    }

    您可以下载 a DLL containing the OAuth.Manager class here .该下载中还有一个帮助文件。或者您可以 view the helpfile online .

    查看使用此管理器的 Windows 窗体示例 here .

    工作实例

    Download a working example使用此处描述的类和技术的命令行工具:

    关于.net - .NET 中带验证的 OAuth,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4002847/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com