如何将Facebook登录v2.0与dotnetopenauth OAuthWebSecurity.RequestAuthentication一起使用

如何将Facebook登录v2.0与dotnetopenauth OAuthWebSecurity.RequestAuthentication一起使用,facebook,asp.net-mvc-4,Facebook,Asp.net Mvc 4,我有一个ASP.Net MVC4应用程序,它是从VS2012中的web模板创建的,因此它使用DotNetOpenAuth和以下代码进行身份验证 internal class ExternalLoginResult : ActionResult { public ExternalLoginResult(string provider, string returnUrl) { Provider = provider;

我有一个ASP.Net MVC4应用程序,它是从VS2012中的web模板创建的,因此它使用DotNetOpenAuth和以下代码进行身份验证

internal class ExternalLoginResult : ActionResult
    {
        public ExternalLoginResult(string provider, string returnUrl)
        {
            Provider = provider;
            ReturnUrl = returnUrl;
        }

        public string Provider { get; private set; }
        public string ReturnUrl { get; private set; }

        public override void ExecuteResult(ControllerContext context)
        {
            OAuthWebSecurity.RequestAuthentication(Provider, ReturnUrl);
        }
    }
我想使用FacebookLoginV2.0,我可以使用JavaScriptSDK实现这一点,但我无法确定是否可以指定oAuth身份验证的版本

我知道可以在URL中指定v2.0,但我看不到可以在何处配置此URL


有人知道怎么做吗?或者它是硬编码到DotNetOpenAuth中的吗?

好的,我找到的解决方案是实现一个定制的OAuth客户端,如下所示(如本文所示)

如您所见,被重写的GetUserData方法引发了一些异常情况。在标准Facebook客户端中,response.username包含用户的Facebook电子邮件地址,但在此实现中data.username包含公共Facebook用户名(时间线地址),这就是我用data.email填充username的原因。这使问题变得复杂,因为一些用户将使用他们的手机而不是他们的电子邮件地址登录,所以我假设response.username(在标准的Facebook客户端中)将返回电子邮件或手机号码,具体取决于用户注册Facebook的方式。那么,我如何决定在此自定义实现中填充用户名的字段?或者使用公共Facebook用户名(时间线地址(例如“joe.blogs.999”)的正确答案是什么?我为什么不这样做


有人有答案吗?

我最终决定,如果Facebook没有提供电子邮件地址,我将要求用户在注册过程中输入。我觉得这样更好,因为它允许我使用唯一的电子邮件作为用户的用户名,以本地用户名和密码注册。如果有人想在MVC5中这样做我也有一个解决办法。
using System;
using System.Net;
using System.Collections.Generic;
using System.Web;
using System.Web.Helpers;
using System.Collections.Specialized;
using Newtonsoft.Json;
using System.Web.Script.Serialization;


namespace ExtensionMethods
{
    public class FacebookV2Client : DotNetOpenAuth.AspNet.Clients.OAuth2Client
    {
        private const string AuthorizationEP = "https://www.facebook.com/v2.0/dialog/oauth";
        private const string TokenEP = "https://graph.facebook.com/v2.0/oauth/access_token";
        private readonly string _appId;
        private readonly string _appSecret;

        public FacebookV2Client(string appId, string appSecret)
            : base("facebook")
        {
            this._appId = appId;
            this._appSecret = appSecret;
        }


        protected override Uri GetServiceLoginUrl(Uri returnUrl)
        {
            return new Uri(
                        AuthorizationEP
                        + "?client_id=" + this._appId
                        + "&redirect_uri=" + HttpUtility.UrlEncode(returnUrl.ToString())
                        + "&scope=email,user_about_me"
                        + "&display=page"
                    );
        }

        protected override IDictionary<string, string> GetUserData(string accessToken)
        {
            WebClient client = new WebClient();
            string content = client.DownloadString(
                "https://graph.facebook.com/me?access_token=" + accessToken
            );
            dynamic data = Json.Decode(content);
            return new Dictionary<string, string> {
                {
                    //The behaviour here is unusual. If you request data.username it holds 
                    //the public Facebook username (Timeline address) instead of the email address that DotetOpenAuth returns as username.
                    //This complicates matters as some users will login with their mobile rather than their email address so what do we use as username?
                    "username",
                    data.email
                },
                {
                    "id",
                    data.id
                },
                {
                    "name",
                    data.name
                },
                {
                    "photo",
                    "https://graph.facebook.com/" + data.id + "/picture"
                },
                {
                    "email",
                    data.email
                }
            };
        }

        protected override string QueryAccessToken(Uri returnUrl, string authorizationCode)
        {
            WebClient client = new WebClient();
            string content = client.DownloadString(
                TokenEP
                + "?client_id=" + this._appId
                + "&client_secret=" + this._appSecret
                + "&redirect_uri=" + HttpUtility.UrlEncode(returnUrl.ToString())
                + "&code=" + authorizationCode
            );

            NameValueCollection nameValueCollection = HttpUtility.ParseQueryString(content);
            if (nameValueCollection != null)
            {
                string result = nameValueCollection["access_token"];
                return result;
            }
            return null;
        }
    }
}
string facebook_appId = "Your appId";
string facebook_appSecret = "Your appSecret";

OAuthWebSecurity.RegisterClient(
    new FacebookV2Client(
        appId: facebook_appId,
        appSecret: facebook_appSecret),
        "facebook", null
);