Asp.net mvc 如何使用ASP.NET MVC 5和OWIN获取Facebook的名字和姓氏值?

Asp.net mvc 如何使用ASP.NET MVC 5和OWIN获取Facebook的名字和姓氏值?,asp.net-mvc,facebook,asp.net-mvc-5,owin,Asp.net Mvc,Facebook,Asp.net Mvc 5,Owin,我知道提供了“姓名”字段,但我更愿意显式访问名字和姓氏。有人能帮忙吗?我仍在为ASP.Net MVC绞尽脑汁。在您的Startup.Auth.csConfigureAuth(IAppBuilder应用程序)方法中,为Facebook设置以下内容: var x = new FacebookAuthenticationOptions(); x.Scope.Add("email"); x.AppId = "*"; x.AppSecret = "**";

我知道提供了“姓名”字段,但我更愿意显式访问名字和姓氏。有人能帮忙吗?我仍在为ASP.Net MVC绞尽脑汁。

在您的Startup.Auth.cs
ConfigureAuth(IAppBuilder应用程序)
方法中,为Facebook设置以下内容:

var x = new FacebookAuthenticationOptions();
        x.Scope.Add("email");
        x.AppId = "*";
        x.AppSecret = "**";
        x.Provider = new FacebookAuthenticationProvider()
        {
            OnAuthenticated = async context =>
                {
                    context.Identity.AddClaim(new System.Security.Claims.Claim("FacebookAccessToken", context.AccessToken));
                    foreach (var claim in context.User)
                    {
                        var claimType = string.Format("urn:facebook:{0}", claim.Key);
                        string claimValue = claim.Value.ToString();
                        if (!context.Identity.HasClaim(claimType, claimValue))
                            context.Identity.AddClaim(new System.Security.Claims.Claim(claimType, claimValue, "XmlSchemaString", "Facebook"));

                    }

                }
        };

        x.SignInAsAuthenticationType = DefaultAuthenticationTypes.ExternalCookie;
        app.UseFacebookAuthentication(x);
        /*
        app.UseFacebookAuthentication(
           appId: "*",
           appSecret: "*");
         * */
        app.UseFacebookAuthentication(new FacebookAuthenticationOptions
        {
            AuthenticationType = "facebook",
            Caption = "Login with Facebook",
            SignInAsAuthenticationType = signInAsType,

            AppId = ConfigurationManager.AppSettings["FacebookAppId"],
            AppSecret = ConfigurationManager.AppSettings["FacebookAppSecret"],

            Provider = new FacebookAuthenticationProvider()
            {
                OnAuthenticated = ctx =>
                {
                    foreach (var claim in ctx.User)
                    {
                        var claimType = $"urn:facebook:{claim.Key}";
                        var claimValue = claim.Value.ToString();
                        if (!ctx.Identity.HasClaim(claim.Key, claimValue))
                        {
                            ctx.Identity.AddClaim(new Claim(claim.Key, claimValue));
                        }
                    }
                    return Task.FromResult(0);
                }
            }
        });
然后使用此选项访问用户的登录信息:

var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
然后通过以下步骤获得第一个名称:

var firstNameClaim = loginInfo.ExternalIdentity.Claims.First(c => c.Type == "urn:facebook:first_name");

在facebook选项范围中添加名字和姓氏

var facebookOptions = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationOptions()
            {
                AppId = "your app id",
                AppSecret = "your app secret",
            };

            facebookOptions.Scope.Add("email");
            facebookOptions.Scope.Add("first_name");
            facebookOptions.Scope.Add("last_name");
            return facebookOptions;

Facebook更改了其权限api。您可以在此处获得更多信息:

名称需要公共配置文件权限

var facebookAuthenticationOptions = new FacebookAuthenticationOptions()
{
    AppId = "appId",
    AppSecret = "key"
};
facebookAuthenticationOptions.Scope.Add("email");
facebookAuthenticationOptions.Scope.Add("public_profile");
app.UseFacebookAuthentication(facebookAuthenticationOptions);
您可以通过以下方式获得:

var loginInfo = await authenticationManager.GetExternalLoginInfoAsync();
loginInfo.ExternalIdentity.Claims.First(c => c.Type == "urn:facebook:name")
authenticationManager是一个实例,您可以使用:

HttpContext.GetOwinContext().Authentication;

不幸的是,由于Facebook使用API update 2.4更改了默认返回值,这种方法不再有效

现在看来,获得第一个_名称等的唯一方法是使用Facebook Graph API()

我还在Katana项目网站上找到了解决这个问题的方法,并且已经提交了一个请求,但是还没有被合并


希望这能为某人节省一点时间;)

截至2017年,这是我的工作代码(感谢上面David Poxon的代码)。确保您已升级到Microsoft.Owin.Security.Facebook的3.1.0版

在Startup.Auth.cs(或在某些情况下为Startup.cs)中,放置以下代码:

app.UseFacebookAuthentication(new FacebookAuthenticationOptions()
{
    AppId = "***",
    AppSecret = "****",
    BackchannelHttpHandler = new HttpClientHandler(),
    UserInformationEndpoint = "https://graph.facebook.com/v2.8/me?fields=id,name,email,first_name,last_name",
    Scope = { "email" },
    Provider = new FacebookAuthenticationProvider()
    {
        OnAuthenticated = async context =>
        {
            context.Identity.AddClaim(new System.Security.Claims.Claim("FacebookAccessToken", context.AccessToken));
            foreach (var claim in context.User)
            {
                var claimType = string.Format("urn:facebook:{0}", claim.Key);
                string claimValue = claim.Value.ToString();
                if (!context.Identity.HasClaim(claimType, claimValue))
                    context.Identity.AddClaim(new System.Security.Claims.Claim(claimType, claimValue, "XmlSchemaString", "Facebook"));
            }
        }
    }
});
var firstName = loginInfo.ExternalIdentity.Claims.First(c => c.Type == "urn:facebook:first_name").Value;
然后在控制器的外部登录回调方法中,添加以下代码:

app.UseFacebookAuthentication(new FacebookAuthenticationOptions()
{
    AppId = "***",
    AppSecret = "****",
    BackchannelHttpHandler = new HttpClientHandler(),
    UserInformationEndpoint = "https://graph.facebook.com/v2.8/me?fields=id,name,email,first_name,last_name",
    Scope = { "email" },
    Provider = new FacebookAuthenticationProvider()
    {
        OnAuthenticated = async context =>
        {
            context.Identity.AddClaim(new System.Security.Claims.Claim("FacebookAccessToken", context.AccessToken));
            foreach (var claim in context.User)
            {
                var claimType = string.Format("urn:facebook:{0}", claim.Key);
                string claimValue = claim.Value.ToString();
                if (!context.Identity.HasClaim(claimType, claimValue))
                    context.Identity.AddClaim(new System.Security.Claims.Claim(claimType, claimValue, "XmlSchemaString", "Facebook"));
            }
        }
    }
});
var firstName = loginInfo.ExternalIdentity.Claims.First(c => c.Type == "urn:facebook:first_name").Value;

同样,要获取姓氏,请使用上面的一行,并将
urn:facebook:first\u name
替换为
urn:facebook:last\u name

facebook已更改其Graph API在升级2.4中返回值的方式。现在,您需要显式指定要返回的所有字段

请参见以下注释:

Graph API在2.4版中的变化

在过去,来自Graph API调用的响应返回一组默认字段。为了减少有效负载大小并改善移动设备上的延迟 我们已经减少了为其返回的默认字段的数量 大多数图形API调用。在v2.4中,您需要声明性地列出 呼叫的响应字段

从facebook获取电子邮件、名字和姓氏:

首先,您需要安装nuget软件包

然后,在startup.Auth.cs中,更改Facebook身份验证的配置,如下所示:

     app.UseFacebookAuthentication(new FacebookAuthenticationOptions
        {
            // put your AppId and AppSecret here. I am reading them from AppSettings 
            AppId = ConfigurationManager.AppSettings["FacebookAppId"],
            AppSecret = ConfigurationManager.AppSettings["FacebookAppSecret"],
            Scope = { "email" },
            Provider = new FacebookAuthenticationProvider
            {
                OnAuthenticated = context =>
                {
                    context.Identity.AddClaim(new System.Security.Claims.Claim("FacebookAccessToken", context.AccessToken));
                    return Task.FromResult(true);
                }
            }
        });

        // this is no longer needed
        //app.UseFacebookAuthentication(
        //   appId: ConfigurationManager.AppSettings["FacebookAppId"],
        //   appSecret: ConfigurationManager.AppSettings["FacebookAppSecret"]);
最后,在AccountController中,将以下代码添加到 ExternalLoginCallback方法:

if (string.Equals(loginInfo.Login.LoginProvider, "facebook", StringComparison.CurrentCultureIgnoreCase))
        {
            var identity = AuthenticationManager.GetExternalIdentity(DefaultAuthenticationTypes.ExternalCookie);
            var access_token = identity.FindFirstValue("FacebookAccessToken");
            var fb = new FacebookClient(access_token);

            // you need to specify all the fields that you want to get back
            dynamic myInfo = fb.Get("/me?fields=email,first_name,last_name"); 
            string email = myInfo.email;
            string firstName = myInfo.first_name;
            string lastName = myInfo.last_name;
        }

请参阅以获取更多您可以获取的参数。

从2019年1月起,我想确认如何执行此操作,并提供一些额外的位(根据答案的编写年份,存在许多相互冲突的信息!)。David和Waqas有最好的答案(IMO)。我使用的是MVC5、AsNetIdentity 2和IdentityServer 3

首先,您的Facebook身份提供商配置:

var x = new FacebookAuthenticationOptions();
        x.Scope.Add("email");
        x.AppId = "*";
        x.AppSecret = "**";
        x.Provider = new FacebookAuthenticationProvider()
        {
            OnAuthenticated = async context =>
                {
                    context.Identity.AddClaim(new System.Security.Claims.Claim("FacebookAccessToken", context.AccessToken));
                    foreach (var claim in context.User)
                    {
                        var claimType = string.Format("urn:facebook:{0}", claim.Key);
                        string claimValue = claim.Value.ToString();
                        if (!context.Identity.HasClaim(claimType, claimValue))
                            context.Identity.AddClaim(new System.Security.Claims.Claim(claimType, claimValue, "XmlSchemaString", "Facebook"));

                    }

                }
        };

        x.SignInAsAuthenticationType = DefaultAuthenticationTypes.ExternalCookie;
        app.UseFacebookAuthentication(x);
        /*
        app.UseFacebookAuthentication(
           appId: "*",
           appSecret: "*");
         * */
        app.UseFacebookAuthentication(new FacebookAuthenticationOptions
        {
            AuthenticationType = "facebook",
            Caption = "Login with Facebook",
            SignInAsAuthenticationType = signInAsType,

            AppId = ConfigurationManager.AppSettings["FacebookAppId"],
            AppSecret = ConfigurationManager.AppSettings["FacebookAppSecret"],

            Provider = new FacebookAuthenticationProvider()
            {
                OnAuthenticated = ctx =>
                {
                    foreach (var claim in ctx.User)
                    {
                        var claimType = $"urn:facebook:{claim.Key}";
                        var claimValue = claim.Value.ToString();
                        if (!ctx.Identity.HasClaim(claim.Key, claimValue))
                        {
                            ctx.Identity.AddClaim(new Claim(claim.Key, claimValue));
                        }
                    }
                    return Task.FromResult(0);
                }
            }
        });
与其他一些答案不同,这将额外请求的字段与默认情况下获得的字段相结合,并将
urn:facebook:
从声明的前面去掉,以便与默认声明命名方案匹配

您不需要添加任何额外的
范围
字段
(至少,不需要添加姓名)。
Microsoft.Owin.Security.Facebook
的4.1版已经为您实现了这一点。这个相关位:

    public FacebookAuthenticationOptions()
        : base(Constants.DefaultAuthenticationType)
    {
        Caption = Constants.DefaultAuthenticationType;
        CallbackPath = new PathString("/signin-facebook");
        AuthenticationMode = AuthenticationMode.Passive;
        Scope = new List<string>();
        BackchannelTimeout = TimeSpan.FromSeconds(60);
        SendAppSecretProof = true;
        _fields = new HashSet<string>();
        CookieManager = new CookieManager();

        AuthorizationEndpoint = Constants.AuthorizationEndpoint;
        TokenEndpoint = Constants.TokenEndpoint;
        UserInformationEndpoint = Constants.UserInformationEndpoint;

        Scope.Add("public_profile");
        Scope.Add("email");
        Fields.Add("name");
        Fields.Add("email");
        Fields.Add("first_name");
        Fields.Add("last_name");
    }

希望这对别人有帮助

对于VB.NET开发人员,这是Startup.Auth.VB中的代码

Dim fb = New FacebookAuthenticationOptions()
        fb.Scope.Add("email")
        fb.AppId = "*"
        fb.AppSecret = "*"
        fb.Provider = New FacebookAuthenticationProvider() With
        {
            .OnAuthenticated = Async Function(context)
                                   context.Identity.AddClaim(New System.Security.Claims.Claim("FacebookAccessToken", context.AccessToken))

                                   For Each claim In context.User
                                       Dim claimType = String.Format("urn:facebook:{0}", claim.Key)
                                       Dim claimValue As String = claim.Value.ToString()
                                       If Not context.Identity.HasClaim(claimType, claimValue) Then context.Identity.AddClaim(New System.Security.Claims.Claim(claimType, claimValue, "XmlSchemaString", "Facebook"))
                                   Next
                               End Function
        }

        fb.SignInAsAuthenticationType = DefaultAuthenticationTypes.ExternalCookie
        app.UseFacebookAuthentication(fb)

名字和姓氏不是有效的作用域。您好,登录信息来自哪里?我们应该把这行代码放在哪里?嗨,我编辑了答案,如果还有什么遗漏,请告诉我。当心!这对我有用;我可以得到名字+姓氏。但是电子邮件总是
null
。另外,你知道一种分别获取名字和姓氏的方法吗?对我来说,name、first_name和last_name是
null
。对我来说是有效的-然后还有一项从提供者不可知的值中获取值的工作,我目前正在做类似于
公共字符串FirstName{get{return chainValue("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname“,//谷歌”urn:facebook:first_name”//facebook);}}