【问题标题】:Getting Twitter Access Secret using DotNetOpenAuth in MVC4在 MVC4 中使用 DotNetOpenAuth 获取 Twitter 访问密钥
【发布时间】:2012-08-30 14:04:32
【问题描述】:

我正在使用 MVC4 创建一个应用程序,该应用程序将授权用户使用 Twitter 并允许他们从该应用程序发送推文。我可以使用 MVC4 中的 BuiltInOAuthClient.Twitter 毫无问题地对用户进行身份验证。 http://www.asp.net/web-pages/tutorials/security/enabling-login-from-external-sites-in-an-aspnet-web-pages-site

我有访问令牌和 oauth_verifier,但我还需要从 Twitter 取回 acess_secret。 https://dev.twitter.com/docs/auth/implementing-sign-twitter

我缺少的是如何将 oauth_verifier 传递回 Twitter 以使用 OAuthWebSecurity 获取访问密钥。

同样,我可以使用 Twitter 登录,但我还需要能够以用户身份使用 twitter。我以前用 TweetSharp 库做过这个,但我试图在这个项目上使用 DotNetOpenAuth。

更新: 我正在使用第一个链接中描述的 OAuthWebSecurity 类来管理身份验证。 AuthConfig 中的 OAuthWebSecurity.RegisterClient 需要一个 DotNetOpenAuth.AspNet.IAuthenticationClient。您不能按照建议将其与 TwitterConsumer 类交换。

我可以使用第一个链接中描述的“内置”DotNetOpenAuth 身份验证部分,或者我可以使用自定义代码来进行完全授权,但我正在尝试找到一种方法来实现这两者。

我可以单独执行此操作,但随后会向用户显示两次 Twitter 对话框(一次用于登录,一次用于授权)。我希望有一种方法可以使用已经连接的身份验证部分,该部分使用 OAuthWebSecurity,但也包含授权部分。

【问题讨论】:

    标签: asp.net-mvc-4 twitter-oauth dotnetopenauth


    【解决方案1】:

    几天来,我一直在用头撞墙,但我终于找到了可行的方法。有兴趣知道它是否是一个有效的解决方案!

    首先,创建一个新的 OAuthClient:

    public class TwitterClient : OAuthClient
    {
        /// <summary>
        /// The description of Twitter's OAuth protocol URIs for use with their "Sign in with Twitter" feature.
        /// </summary>
        public static readonly ServiceProviderDescription TwitterServiceDescription = new ServiceProviderDescription
        {
            RequestTokenEndpoint =
                new MessageReceivingEndpoint(
                    "https://api.twitter.com/oauth/request_token",
                    HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest),
            UserAuthorizationEndpoint =
                new MessageReceivingEndpoint(
                    "https://api.twitter.com/oauth/authenticate",
                    HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest),
            AccessTokenEndpoint =
                new MessageReceivingEndpoint(
                    "https://api.twitter.com/oauth/access_token",
                    HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest),
            TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement() },
        };
    
        public TwitterClient(string consumerKey, string consumerSecret) :
            base("twitter", TwitterServiceDescription, consumerKey, consumerSecret) { }
    
        /// Check if authentication succeeded after user is redirected back from the service provider.
        /// The response token returned from service provider authentication result. 
        protected override AuthenticationResult VerifyAuthenticationCore(AuthorizedTokenResponse response)
        {
            string accessToken = response.AccessToken;
            string accessSecret = (response as ITokenSecretContainingMessage).TokenSecret;
            string userId = response.ExtraData["user_id"];
            string userName = response.ExtraData["screen_name"];
    
            var extraData = new Dictionary<string, string>()
                                {
                                    {"accesstoken", accessToken},
                                    {"accesssecret", accessSecret}
                                };
            return new AuthenticationResult(
                isSuccessful: true,
                provider: ProviderName,
                providerUserId: userId,
                userName: userName,
                extraData: extraData);
        }
    }
    

    重要的部分是将响应转换为 ITokenSecretContainingMessage。似乎响应一直都有 TokenSecret,但它只是在内部属性上。通过投射它,您可以访问公共财产。我不能说我喜欢这样做,但我也不明白为什么 DotNetOpenAuth Asp.Net 团队首先隐藏了该属性。一定有充分的理由。

    然后您在 AuthConfig 中注册此客户端:

    OAuthWebSecurity.RegisterClient( new TwitterClient(
        consumerKey: "",
        consumerSecret: ""), "Twitter", null);
    

    现在,在 AccountController 的 ExternalLoginCallback 方法中,extraData 字典中提供了 accessSecret。

    【讨论】:

    • 这很好。我赞成。 :) 它是“隐藏的”,因为设计是将访问令牌秘密隐藏在客户端提供的令牌管理器中。但是,您从此处派生的 OAuthClient 来自 ASP.NET 团队,该团队试图简化体验并对您隐藏令牌管理器。你的解决方案很好。在 DNOA 的未来版本中,获取此信息将更加容易。
    • 感谢您抽出宝贵时间查看,很高兴知道我还没有想出一个疯狂的解决方案!我没有说它是 .Net 团队的客户,为抨击 DNOA 团队道歉。 :)
    • 非常感谢这个很棒的解决方案!
    • 谢谢,这非常有用。
    【解决方案2】:

    DotNetOpenAuth.AspNet.Clients.TwitterClient 类只允许认证,不允许授权。因此,如果您使用该类,您将无法以该用户的身份发布推文。

    相反,您可以使用DotNetOpenAuth.ApplicationBlock.TwitterConsumer,它没有此限制,您甚至可以将此类型的源代码复制到您的应用程序中并根据需要对其进行扩展。

    您应该能够增强TwitterConsumer 类(一旦将其复制到您自己的项目中)以实现所需的接口,以便OAuthWebSecurity 类将接受它。否则,您可以自己直接使用TwitterConsumer 来验证和授权您的Web 应用程序,这样用户只能看到一次Twitter,但您可以获得所需的所有控制权。毕竟,早在OAuthWebSecurity 出现之前,使用 ASP.NET 的人们就已经使用 TwitterConsumer 登录和授权后续调用 Twitter。

    【讨论】:

    • 看起来 TwitterConsumer 不能与 AuthConfig 中使用的 OAuthWebSecurity 类一起使用。
    • @AndrewArnott 我很想知道你对这个问题的解决方案的想法,我从各种 SO 答案和论坛帖子中拼凑起来。肯定有一个方面我不确定(转换到界面)!
    • Paul,您的解决方案看起来很棒。
    【解决方案3】:

    对于在 AuthConfig.cs 而不是 Microsoft.Web.WebPages.OAuth(MVC4 Internet 应用程序)中引用 Microsoft.AspNet.Membership.OpenAuth 的 WebForms 项目模板,我能够修改 Paul Manzotti 的答案以使其工作:

    1. 创建一个派生自 DotNetOpenAuth.AspNet.Clients.TwitterClient 的自定义 Twitter 客户端类

      公共类 CustomTwitterClient : TwitterClient { 公共CustomTwitterClient(字符串消费者密钥,字符串消费者秘密): 基数(consumerKey,consumerSecret){}

      protected override AuthenticationResult VerifyAuthenticationCore(AuthorizedTokenResponse response)
      {
          //return base.VerifyAuthenticationCore(response);
          string accessToken = response.AccessToken;
          string accessSecret = (response as ITokenSecretContainingMessage).TokenSecret;
          string userId = response.ExtraData["user_id"];
          string userName = response.ExtraData["screen_name"];
      
          var extraData = new Dictionary<string, string>()
                          {
                              {"accesstoken", accessToken},
                              {"accesssecret", accessSecret}
                          };
          return new AuthenticationResult(
              isSuccessful: true,
              provider: ProviderName,
              providerUserId: userId,
              userName: userName,
              extraData: extraData);
      }
      

      }

    2. 在 AuthConfig.cs 中添加自定义客户端

      public static void RegisterOpenAuth()
      {
          OpenAuth.AuthenticationClients.Add("Twitter", () => new CustomTwitterClient(
              consumerKey: ConfigurationManager.AppSettings["twitterConsumerKey"], 
              consumerSecret: ConfigurationManager.AppSettings["twitterConsumerSecret"]));
      }
      

    陶道!现在您可以访问密钥了。

    【讨论】:

      【解决方案4】:

      您可以通过设计自己的 TokenManager 从 OAuthWebSecurity 中提取 oauth_token_secret。您可以在 OAuthWebSecurity.RegisterClient 中注册 Twitter 客户端时注册令牌管理器。

      我使用此方法提取所需的值,以便能够绕过 Linq-to-Twitter 库的授权步骤。

      我很快就会在我的博客上发布我的解决方案。

      【讨论】:

      • 你有没有机会把关于这个的博文放在一起?
      猜你喜欢
      • 2015-04-17
      • 2014-09-12
      • 1970-01-01
      • 1970-01-01
      • 2020-12-14
      • 2013-05-10
      • 2012-07-05
      • 2011-07-07
      • 1970-01-01
      相关资源
      最近更新 更多