Utwórz nowy obiekt Microsoft.Owin.Security.Facebook.AuthenticationOptions w pliku Startup.ConfigureAuth (StartupAuth.cs), przekazując go składnikowi FacebookAppId, FacebookAppSecret i nowemu dostawcy uwierzytelniania. Użyjesz wyrażenia lambda do przekazania metody OnAuthenticated, aby dodać kod do roszczenia do tożsamości, które zawierają wartości wyodrębnione z context.Identity. Będzie to domyślnie obejmować access_token. Musisz dodać e-mail do zakresu. Inne właściwości użytkownika są dostępne z context.User (patrz link na dole na przykład).
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);
}
W AccountController, wyodrębnić ClaimsIdentity z AuthenticationManager pomocą cookie zewnętrznej. Dodaję go następnie do tożsamości utworzonej za pomocą pliku cookie aplikacji. Zignorowałem wszelkie roszczenia, które zaczynają się od "... schemas.xmlsoap.org/ws/2005/05/identity/claims", ponieważ wydawało się, że zepsuło to logowanie.
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);
}
}
}
I wreszcie, chcę, aby wyświetlić cokolwiek wartości nie są od lokalnych władz. Utworzono częściowy widok _WewnętrznyUserPropertiesListPartial, który pojawia się na /Account/Manage page. Otrzymuję oświadczenia, które wcześniej zapisałem w pliku AuthenticationManager.User.Claims, a następnie przekazuję je do widoku.
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>();
}
I tylko żeby być dokładny, widok:
_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>
}
Przykład pracę i kompletny kod jest na GitHub: https://github.com/johndpalm/IdentityUserPropertiesSample
I wszelkie opinie, poprawne jony lub ulepszenia byłyby docenione.
Dziękujemy! Sztuką jest wywołanie 'facebookOptions.Scope.Add (" email ")', a następnie, jak mówisz, dane e-mail są automatycznie dodawane jako roszczenie bez konieczności analizowania danych json. Jednak mam teraz nowy problem: podczas używania twojego kodu, wywołanie 'AuthenticationManager.GetExternalIdentity' w wywołaniu zwrotnym zwróci wartość null zamiast instancji' ClaimsIdentity'. Czy masz pojęcie, co może się dziać? (i tak, dodaję odpowiedni identyfikator aplikacji i sekret do obiektu facebookOptions) – Konamiman
Ok, znalazłem rozwiązanie do zbadania stąd: http://forums.asp.net/p/1927914/5516103.aspx?p=True&t= 635154678323993438. Następujące elementy muszą zostać dodane do inicjowania obiektu facebookOptions: 'SignInAsAuthenticationType =" External "'. Przyjmuję twoją odpowiedź, ale może chcesz ją edytować, aby zawierała te sztuczki. :-) – Konamiman
Czy możesz podzielić się przykładowym kodem, aby pokazać, w jaki sposób uzyskałeś dodatkowe informacje (np. BirthDate) w zadaniu callback actionresult? – Santosh