在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,我提取使用外部餅乾從所述的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上的局部視圖_ExternalUserPropertiesListPartial。我得到我以前從AuthenticationManager.User.Claims存儲的聲明,然後將其傳遞給視圖。
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
和任何反饋,更正離子,或改進將不勝感激。
謝謝!訣竅是調用'facebookOptions.Scope.Add(「email」)',然後如您所說,電子郵件數據會自動添加爲聲明,而無需解析json數據。然而,我現在有一個新問題:當使用你的代碼時,在回調中調用'AuthenticationManager.GetExternalIdentity'將返回null而不是'ClaimsIdentity'的實例。你有什麼想法可以發生? (是的,我將正確的應用程序ID和祕密添加到facebookOptions對象) – Konamiman
好吧,找到解決方案從這裏調查:http://forums.asp.net/p/1927914/5516103.aspx?p=True&t= 635154678323993438。以下必須添加到facebookOptions對象初始化中:'SignInAsAuthenticationType =「External」'。我會接受你的答案,但也許你想編輯它,使其包含這些技巧。 :-) – Konamiman
您可以請分享示例代碼以顯示您如何檢索回調actionresult任務內的其他信息(比如說BirthDate)嗎? – Santosh