在MVC4中使用DotNetOpenAuth获取Twitter访问密钥

时间:2012-08-30 14:04:32

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

我正在使用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,但也可以使用授权文件。

4 个答案:

答案 0 :(得分:10)

我现在已经用头撞墙了几天,但我终于有了一些有用的东西。有兴趣知道它是否是一个有效的解决方案!

首先,创建一个新的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,但它仅在内部属性上。通过投射,您可以访问公共财产。我不能说我是这样做的粉丝,但后来我也不明白为什么Asp.Net团队首先隐藏了这个属性 OpenNetOuthAuth 。必须有充分的理由。

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

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

现在,在AccountController的ExternalLoginCallback方法中,accessSecret在ExtraData字典中可用。

答案 1 :(得分:2)

DotNetOpenAuth.AspNet.Clients.TwitterClient类仅允许身份验证,而不允许授权。因此,如果您使用该类,则无法将推文发布为该用户。

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

您应该能够增强TwitterConsumer类(一旦将其复制到您自己的项目中)以实现所需的接口,以便OAuthWebSecurity类接受它。否则,您可以直接使用TwitterConsumer对您的网络应用进行身份验证和授权,这样用户只能看到Twitter一次,但您可以获得所需的全部控制权。毕竟,使用ASP.NET的人们已经使用TwitterConsumer来登录和授权,以便在OAuthWebSecurity甚至存在之前很久就调用Twitter。

答案 2 :(得分:1)

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

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

    公共类CustomTwitterClient:TwitterClient {     public CustomTwitterClient(string consumerKey,string consumerSecret):         base(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"]));
    }
    
  3. 钽道!现在你可以访问秘密。

答案 3 :(得分:0)

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

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

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