gpt4 book ai didi

asp.net-mvc - 如何使用 ASP.NET Identity (OWIN) 访问 Facebook 私有(private)信息?

转载 作者:行者123 更新时间:2023-12-02 18:46:37 25 4
gpt4 key购买 nike

我正在 ASP.NET MVC 5 中开发一个网站(当前使用 RC1 版本)。该网站将使用 Facebook 进行用户身份验证和检索初始个人资料数据。

对于身份验证系统,我使用新的基于 OWIN 的 ASP.NET Identity 引擎 ( http://blogs.msdn.com/b/webdev/archive/2013/07/03/understanding-owin-forms-authentication-in-mvc-5.aspx ),因为它大大简化了与外部提供商进行身份验证的过程。

问题是,一旦用户首次登录,我想从 Facebook 个人资料中获取其电子邮件地址,但此数据不包含在生成的声明中。所以我考虑了这些替代方案来获取地址:

  1. 指示 ASP.NET Identity 引擎将电子邮件地址包含在从 Facebook 检索然后转换的数据集到 claim 。我不知道这是否可能。

  2. 使用 Facebook 图形 API( https://developers.facebook.com/docs/getting-started/graphapi ) 至使用 Facebook 用户 ID(即包含在 claim 数据中)。但如果用户有,这将不起作用将他的电子邮件地址设置为私有(private)地址。

  3. 使用 Facebook 图形 API,但指定“me”而不是 Facebook 用户 ID(https://developers.facebook.com/docs/reference/api/user)。但是一个需要访问 token ,但我不知道如何(或者如果是完全可能)检索 ASP.NET 使用的访问 token 获取用户数据。

所以问题是:

  1. 如何指示 ASP.NET Identity 引擎进行检索来自 Facebook 的附加信息并将其包含在声明中数据?

  2. 或者,我如何检索生成的访问 token 我可以亲自询问 Facebook 吗?

谢谢!

注意:对于身份验证系统,我的应用程序使用基于此 SO 答案中链接的示例项目的代码:https://stackoverflow.com/a/18423474/4574

最佳答案

在 Startup.ConfigureAuth (StartupAuth.cs) 中创建一个新的 Microsoft.Owin.Security.Facebook.AuthenticationOptions 对象,并向其传递 FacebookAppId、FacebookAppSecret 和新的 AuthenticationProvider。您将使用 lambda 表达式向 OnAuthenticated 方法传递一些代码,以将声明添加到包含从 context.Identity 中提取的值的身份。默认情况下,这将包括 access_token。您必须将电子邮件添加到范围。其他用户属性可从 context.User 获得(例如,请参见底部的链接)。

StartUp.Auth.cs

// Facebook : Create New App
// https://dev.twitter.com/apps
if (ConfigurationManager.AppSettings.Get("FacebookAppId").Length > 0)
{
var facebookOptions = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationOptions()
{
AppId = ConfigurationManager.AppSettings.Get("FacebookAppId"),
AppSecret = ConfigurationManager.AppSettings.Get("FacebookAppSecret"),
Provider = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationProvider()
{
OnAuthenticated = (context) =>
{
context.Identity.AddClaim(new System.Security.Claims.Claim("urn:facebook:access_token", context.AccessToken, XmlSchemaString, "Facebook"));
context.Identity.AddClaim(new System.Security.Claims.Claim("urn:facebook:email", context.Email, XmlSchemaString, "Facebook"));
return Task.FromResult(0);
}
}

};
facebookOptions.Scope.Add("email");
app.UseFacebookAuthentication(facebookOptions);
}

在 AccountController 中,我使用外部 cookie 从 AuthenticationManager 中提取 ClaimsIdentity。然后,我将其添加到使用应用程序 cookie 创建的身份中。我忽略了任何以“...schemas.xmlsoap.org/ws/2005/05/identity/claims”开头的声明,因为它似乎破坏了登录。

AccountController.cs

private async Task SignInAsync(CustomUser user, bool isPersistent)
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);

// Extracted the part that has been changed in SignInAsync for clarity.
await SetExternalProperties(identity);

AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
}

private async Task SetExternalProperties(ClaimsIdentity identity)
{
// get external claims captured in Startup.ConfigureAuth
ClaimsIdentity ext = await AuthenticationManager.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);

if (ext != null)
{
var ignoreClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims";
// add external claims to identity
foreach (var c in ext.Claims)
{
if (!c.Type.StartsWith(ignoreClaim))
if (!identity.HasClaim(c.Type, c.Value))
identity.AddClaim(c);
}
}
}

最后,我想显示任何不是来自本地权威机构的值。我创建了一个出现在 /Account/Manage page 上的部分 View _ExternalUserPropertiesListPartial 。我从 AuthenticationManager.User.Claims 获取之前存储的声明,然后将其传递到 View 。

AccountController.cs

[ChildActionOnly]
public ActionResult ExternalUserPropertiesList()
{
var extList = GetExternalProperties();
return (ActionResult)PartialView("_ExternalUserPropertiesListPartial", extList);
}

private List<ExtPropertyViewModel> GetExternalProperties()
{
var claimlist = from claims in AuthenticationManager.User.Claims
where claims.Issuer != "LOCAL AUTHORITY"
select new ExtPropertyViewModel
{
Issuer = claims.Issuer,
Type = claims.Type,
Value = claims.Value
};

return claimlist.ToList<ExtPropertyViewModel>();
}

为了彻底,观点:

_ExternalUserPropertiesListPartial.cshtml

@model IEnumerable<MySample.Models.ExtPropertyViewModel>

@if (Model != null)
{
<legend>External User Properties</legend>
<table class="table">
<tbody>
@foreach (var claim in Model)
{
<tr>
<td>@claim.Issuer</td>
<td>@claim.Type</td>
<td>@claim.Value</td>
</tr>
}
</tbody>
</table>
}

工作示例和完整代码位于 GitHub 上:https://github.com/johndpalm/IdentityUserPropertiesSample

如有任何反馈、更正或改进,我们将不胜感激。

关于asp.net-mvc - 如何使用 ASP.NET Identity (OWIN) 访问 Facebook 私有(private)信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18942196/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com