Asp.net mvc 如何使用ASP.NET身份(OWIN)访问Facebook私人信息?
我正在用ASP.NETMVC5开发一个网站(目前使用的是RC1版本)。该网站将使用Facebook进行用户身份验证和检索初始配置文件数据 对于身份验证系统,我使用新的基于OWIN的ASP.NET Identity engine(),因为它大大简化了与外部提供者进行身份验证的过程 问题是,一旦用户首次登录,我想从Facebook个人资料中获取其电子邮件地址,但生成的声明中不包括这些数据。因此,我考虑了这些备选方案以获得地址:Asp.net mvc 如何使用ASP.NET身份(OWIN)访问Facebook私人信息?,asp.net-mvc,facebook-graph-api,asp.net-mvc-5,owin,asp.net-identity,Asp.net Mvc,Facebook Graph Api,Asp.net Mvc 5,Owin,Asp.net Identity,我正在用ASP.NETMVC5开发一个网站(目前使用的是RC1版本)。该网站将使用Facebook进行用户身份验证和检索初始配置文件数据 对于身份验证系统,我使用新的基于OWIN的ASP.NET Identity engine(),因为它大大简化了与外部提供者进行身份验证的过程 问题是,一旦用户首次登录,我想从Facebook个人资料中获取其电子邮件地址,但生成的声明中不包括这些数据。因此,我考虑了这些备选方案以获得地址: 指示ASP.NET标识引擎将电子邮件地址包含在 从Facebook检索并
注意:对于身份验证系统,我的应用程序使用基于此SO答案中链接的示例项目的代码:要从facebook检索其他信息,可以指定配置facebook身份验证选项时要包含的范围。通过实现提供程序的OnAuthenticated方法,可以获取检索到的其他信息,如下所示:
var facebookOptions = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationOptions()
{
Provider = new FacebookAuthenticationProvider()
{
OnAuthenticated = (context) =>
{
// All data from facebook in this object.
var rawUserObjectFromFacebookAsJson = context.User;
// Only some of the basic details from facebook
// like id, username, email etc are added as claims.
// But you can retrieve any other details from this
// raw Json object from facebook and add it as claims here.
// Subsequently adding a claim here will also send this claim
// as part of the cookie set on the browser so you can retrieve
// on every successive request.
context.Identity.AddClaim(...);
return Task.FromResult(0);
}
}
};
//Way to specify additional scopes
facebookOptions.Scope.Add("...");
app.UseFacebookAuthentication(facebookOptions);
根据我看到的代码,如果facebook发送了电子邮件,则该电子邮件已被检索并添加为声明。你看不见吗 以下是一些对您有帮助的步骤。我正在写一篇博文,但这需要一段时间。。。 -在Fb provider中添加作用域,并将Fb返回的数据添加为声明
app.UseFacebookAuthentication(new FacebookAuthenticationOptions()
{
AppId = "",
AppSecret = "",
//Scope = "email,user_about_me,user_hometown,friends_about_me,friends_photos",
Provider = new FacebookAuthenticationProvider()
{
OnAuthenticated = async context =>
{
foreach (var x in context.User)
{
context.Identity.AddClaim(new System.Security.Claims.Claim(x.Key, x.Value.ToString()));
}
//Get the access token from FB and store it in the database and use FacebookC# SDK to get more information about the user
context.Identity.AddClaim(new System.Security.Claims.Claim("FacebookAccessToken", context.AccessToken));
}
},
SignInAsAuthenticationType = "External",
});
- 使用访问令牌并致电Facebook C#SDK获取用户的好友列表
var claimsIdentity = HttpContext.User.Identity as ClaimsIdentity; var access_token = claimsIdentity.FindAll("FacebookAccessToken").First().Value; var fb = new FacebookClient(access_token); dynamic myInfo = fb.Get("/me/friends"); var friendsList = new List<FacebookViewModel>(); foreach (dynamic friend in myInfo.data) { friendsList.Add(new FacebookViewModel() { Name = friend.name, ImageURL = @"https://graph.facebook.com/" + friend.id + "/picture?type=large" }); //Response.Write("Name: " + friend.name + "<br/>Facebook id: " + friend.id + "<br/><br/>"); }
var claimsIdentity=HttpContext.User.Identity作为claimsIdentity; var access_token=claimsIdentity.FindAll(“FacebookAccessToken”).First().Value; var fb=新的FacebookClient(访问令牌); 动态myInfo=fb.Get(“/me/friends”); var friendsList=新列表(); foreach(myInfo.data中的动态好友) { 添加(新的FacebookViewModel(){Name=friend.Name,ImageURL=@)https://graph.facebook.com/“+friend.id+”/picture?type=large“}); //回复。写下(“姓名:“+friend.Name+”
Facebook id:“+friend.id+”
); }
// 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提取ClaimSideEntity。然后,我将其添加到使用应用程序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);
}
}
}
[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,它显示在上。我从AuthenticationManager.User.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);
}
}
}
[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>();
}
[ChildActionOnly]
公共操作结果ExternalUserPropertiesList()
{
var extList=GetExternalProperties();
返回(ActionResult)PartialView(“\u ExternalUserPropertiesListPartial”,extList);
}
私有列表GetExternalProperties()
{
var claimlist=来自AuthenticationManager.User.claims中的声明
何处索赔。发卡机构!=“地方当局”
选择新的ExtPropertyViewModel
{
发行人=索赔。发行人,
类型=索赔。类型,
价值=索赔。价值
};
返回claimlist.ToList();
}
更详细地说,以下观点:
_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>
}
@model IEnumerable
@如果(型号!=null)
{
外部用户属性
@foreach(模型中的var索赔)
{
@索赔人
@索赔.类型
@索赔价值
}
}
GitHub上提供了工作示例和完整代码:
如有任何反馈、更正或改进,我们将不胜感激。在
Startup.Auth中,这对我来说非常有效:
var facebookOptions = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationOptions() {
AppId = "*",
AppSecret = "**"
};
facebookOptions.Scope.Add("email");
app.UseFacebookAuthentication(facebookOptions);
然后在方法ExternalLoginCallback
或externalloginconconfirmation
中,您将收到以下电子邮件:
ClaimsIdentity ext = await AuthenticationManager.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);
var email = ext.Claims.First(x => x.Type.Contains("emailaddress")).Value;
您需要创建一个FacebookAuthenticationOptions
的实例,并配置提供程序
。Provider
包含一个名为OnAuthenticated
的事件,该事件在您登录时触发
var facebookOptions = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationOptions
{
Provider = new FacebookAuthenticationProvider()
{
OnAuthenticated = (context) =>
{
context.Identity.AddClaim(new System.Security.Claims.Claim("urn:facebook:access_token", context.AccessToken, ClaimValueTypes.String, "Facebook"));
return Task.FromResult(0);
}
},
// You can store these on AppSettings
AppId = ConfigurationManager.AppSettings["facebook:AppId"],
AppSecret = ConfigurationManager.AppSettings["facebook:AppSecret"]
};
app.UseFacebookAuthentication(facebookOptions);
在上述代码中
string accessToken = FacebookAccessToken;
context.Identity.AddClaim(new System.Security.Claims.Claim("urn:facebook:username",
context.User.Value<string>("username"), ClaimValueTypes.String, "Facebook"));
context.Identity.AddClaim(new System.Security.Claims.Claim("urn:facebook:name",
context.User.Value<string>("name"), ClaimValueTypes.String, "Facebook"));
facebookOptions.Scope.Add("email");
context.User.Value<string>("email");