【问题标题】:How to get OAuth working with DotNetOpenAuth and Evernote?如何让 OAuth 与 DotNetOpenAuth 和 Evernote 一起使用?
【发布时间】:2013-06-27 00:09:48
【问题描述】:

我正在尝试使用 DotNetOpenAuth 库编写一个 C# ASP.NET MVC 应用程序,该库使用 OAuth 连接到 Evernote 沙箱,但我无法让它工作。在调用回调之前,我的应用程序都很好,但是当我尝试在this diagram 的第 10 步中请求交换临时凭据时,它会失败并显示 401 Unauthorized。

我的回调如下所示:

    public ActionResult OAuthCallback()
    {
        var webConsumer = CreateWebConsumer();
        var accessTokenResponse = webConsumer.ProcessUserAuthorization();

        if (accessTokenResponse != null)
        {
            AccessToken = accessTokenResponse.AccessToken;
        }


        return RedirectToAction("Index");
    }

异常发生在var accessTokenResponse = webConsumer.ProcessUserAuthorization(); 行,这是尝试凭据交换的原因。

Fiddler 显示如下:

调用回调:

GET http://localhost:22297/Home/OAuthCallback?oauth_token=GiddyUpHorsey.13F82BDC264.687474703A2F2F6C6F63616C686F73743A32323239372F486F6D652F4F4175746843616C6C6261636B.CFB67142944B4EB90148DDAFE2120A71&oauth_verifier=93534C2B04F862E57B30D738C3569242 HTTP/1.1
Accept: text/html, application/xhtml+xml, */*
Connection: Keep-Alive
Accept-Language: en-NZ
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)
Pragma: no-cache
Accept-Encoding: gzip, deflate
Host: localhost:22297
DNT: 1
Cache-Control: no-cache

请求令牌交换:

webConsumer.ProcessUserAuthorization();触发。

POST https://sandbox.evernote.com/oauth HTTP/1.1
Content-Type: application/x-www-form-urlencoded; charset=utf-8
User-Agent: DotNetOpenAuth.Core/4.3.0.13117
Host: sandbox.evernote.com
Cache-Control: no-store,no-cache
Pragma: no-cache
Content-Length: 369
Expect: 100-continue

oauth_verifier=93534C2B04F862E57B30D738C3569242&oauth_token=GiddyUpHorsey.13F82BDC264.687474703A2F2F6C6F63616C686F73743A32323239372F486F6D652F4F4175746843616C6C6261636B.CFB67142944B4EB90148DDAFE2120A71&oauth_consumer_key=GiddyUpHorsey&oauth_nonce=cHABo5jv&oauth_signature_method=PLAINTEXT&oauth_signature=4c0dd81215379f75%26&oauth_version=1.0&oauth_timestamp=1372288061

回应:

HTTP/1.1 401 Unauthorized
Set-Cookie: JSESSIONID=4CDCD690AEAD69D952CEE4CBED5AC8DC; Path=/
Content-Type: text/html;charset=ISO-8859-1
Content-Language: en
Date: Wed, 26 Jun 2013 23:07:48 GMT
Server: Evernote/1.0
Content-Length: 1587


<html>
.....
        <div class="page-header">
          <h1>
            Oops, we encountered an error.</h1>
        </div>
        <div>
          <p>
            Sorry, we've encountered an unexpected error.</p>
        </div>
        <div class="clear"></div>
      </div>
...
</html>

(我从响应中删除了大部分 HTML)

为什么会因为 401 Unauthorized 而失败?

【问题讨论】:

    标签: c# oauth dotnetopenauth evernote


    【解决方案1】:

    我不确定你是否曾经让这个工作正常,但我今天早上在玩 Evernote、OpenAuth 和 C#,并设法让这一切正常工作。我已经整理了一篇博文/库,解释了经验并在此处概述了如何使用 MVC -http://www.shaunmccarthy.com/evernote-oauth-csharp/ - 它使用 AsyncOAuth 库:https://github.com/neuecc/AsyncOAuth

    我围绕 AsyncOAuth 编写了一个包装器,您可能会在这里发现它很有用:https://github.com/shaunmccarthy/AsyncOAuth.Evernote.Simple

    需要注意一个棘手的问题 - Evernote 端点(/oauth 和 /OAuth.action)区分大小写

    // Download the library from https://github.com/shaunmccarthy/AsyncOAuth.Evernote.Simple
    
    // Configure the Authorizer with the URL of the Evernote service,
    // your key, and your secret. 
    var EvernoteAuthorizer = new EvernoteAuthorizer(
        "https://sandbox.evernote.com", 
        "slyrp-1234", // Not my real id / secret :)
        "7acafe123456badb123");
    
    // First of all, get a request token from Evernote - this causes a 
    // webrequest from your server to Evernote.
    // The callBackUrl is the URL you want the user to return to once
    // they validate the app
    var requestToken = EvernoteAuthorizer.GetRequestToken(callBackUrl);
    
    // Persist this token, as we are going to redirect the user to 
    // Evernote to Authorize this app
    Session["RequestToken"] = requestToken;
    
    // Generate the Evernote URL that we will redirect the user to in
    // order to 
    var callForwardUrl = EvernoteAuthorizer.BuildAuthorizeUrl(requestToken);
    
    // Redirect the user (e.g. MVC)
    return Redirect(callForwardUrl);
    
    // ... Once the user authroizes the app, they get redirected to callBackUrl
    
    // where we parse the request parameter oauth_validator and finally get
    // our credentials
    // null = they didn't authorize us
    var credentials = EvernoteAuthorizer.ParseAccessToken(
        Request.QueryString["oauth_verifier"], 
        Session["RequestToken"] as RequestToken);
    
    // Example of how to use the credential with Evernote SDK
    var noteStoreUrl = EvernoteCredentials.NotebookUrl;
    var noteStoreTransport = new THttpClient(new Uri(noteStoreUrl));
    var noteStoreProtocol = new TBinaryProtocol(noteStoreTransport);
    var noteStore = new NoteStore.Client(noteStoreProtocol);
    List<Notebook> notebooks = client.listNotebooks(EvernoteCredentials.AuthToken);
    

    【讨论】:

    • 我尝试了您的代码,但奇怪的是,我仍然收到 401 Unauthorized 错误。我想知道这个问题是否与我的环境有关。该应用程序必须通过代理服务器才能与外界通信。也许这与它有关。
    • 您在哪一步收到 401 错误?用户是否看到 401,还是在 GetRequestToken 期间发生?
    • 在此行调用sandbox.evernote.com/oauth时出现:var result = await base.GetAccessToken(OAuthUrl, token, oauth_verifier, null, null);AsyncEvernoteAuthorizer.cs:Line 115。用户在印象笔记中授权了应用程序,然后出现错误。用户看到有关 401 Unauthorized 异常的 YSOD。
    • 所以此时有两个可能的问题 - 要么您没有收到 oauth_verifier(检查它是否已填充),要么您的令牌为空(检查它,并且密钥和 Secret 具有正确的值)。也许您忘记在获取令牌(GetRequestToken)和重定向用户并且他们回来之间的会话中存储令牌?
    • 预期值在调试器中应该看起来像这样 - 值发生了一些变化以保护无辜 ;) OAuthUrl="sandbox.evernote.com/oauth", token.Key="YOUR-APP-ID.1419B6610F9。 687474703A546F6B656E433.BFE5972454CD", token.Secret= "5C1AC31B08E5FC321885B7BD6904735C", oauth_verifier="2090AA4007C2990891719CCCBFFAA3B3"
    猜你喜欢
    • 2018-07-10
    • 2011-11-26
    • 2015-11-21
    • 1970-01-01
    • 2011-11-22
    • 1970-01-01
    • 2018-05-03
    • 1970-01-01
    • 2013-11-20
    相关资源
    最近更新 更多