Ответ 1
Мне удалось создать рабочий пример с использованием шаблонов RTM MVC 5, бит OWIN и ASP.NET. Вы можете найти полный источник и ссылку на живой рабочий пример здесь: https://github.com/johndpalm/IdentityUserPropertiesSample
Вот что сработало для меня:
Создайте новое (введите имя поставщика здесь) Объект AuthenticationOptions в Startup.ConfigureAuth(StartupAuth.cs), передав ему идентификатор клиента, секрет клиента и новый AuthenticationProvider. Вы будете использовать лямбда-выражение для передачи методу OnAuthenticated некоторого кода для добавления претензий к идентификатору, который содержит значения, которые вы извлекаете из контекста. Идентичность.
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"));
foreach (var x in context.User)
{
var claimType = string.Format("urn:facebook:{0}", x.Key);
string claimValue = x.Value.ToString();
if (!context.Identity.HasClaim(claimType, claimValue))
context.Identity.AddClaim(new System.Security.Claims.Claim(claimType, claimValue, XmlSchemaString, "Facebook"));
}
return Task.FromResult(0);
}
}
};
app.UseFacebookAuthentication(facebookOptions);
}
ПРИМЕЧАНИЕ. Поставщик auth Facebook работает с кодом, используемым здесь. Если вы используете этот же код у поставщика учетной записи Microsoft (или поставщик Foursquare, который я создал с использованием кода учетной записи MS в качестве модели), он не может войти в систему. Если вы выберете только параметр access_token, он будет работать нормально. Похоже, что некоторые параметры нарушают процесс входа в систему. (Проблема была обнаружена на katanaproject.codeplex.com, если ваш интерес к этому интересен.) Я обновлю, если найду причину. Я много не делал с Twitter или Google, не проверяя, что я могу получить access_token.
var msaccountOptions = new Microsoft.Owin.Security.MicrosoftAccount.MicrosoftAccountAuthenticationOptions()
{
ClientId = ConfigurationManager.AppSettings.Get("MicrosoftClientId"),
ClientSecret = ConfigurationManager.AppSettings.Get("MicrosoftClientSecret"),
Provider = new Microsoft.Owin.Security.MicrosoftAccount.MicrosoftAccountAuthenticationProvider()
{
OnAuthenticated = (context) =>
{
context.Identity.AddClaim(new System.Security.Claims.Claim("urn:microsoftaccount:access_token", context.AccessToken, XmlSchemaString, "Microsoft"));
return Task.FromResult(0);
}
}
};
app.UseMicrosoftAccountAuthentication(msaccountOptions);
В AccountController я извлекаю ClaimsIdentity из AuthenticationManager, используя внешний файл cookie. Затем я добавляю его в идентификатор, созданный с помощью 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);
}
}
}
И, наконец, я хочу отображать любые значения из LOCAL AUTHORITY. Я создал частичный вид _ExternalUserPropertiesListPartial, который отображается на странице /Account/Manage. Я получаю претензии, которые я ранее хранил в AuthenticationManager.User.Claim, а затем передал их в представление.
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
И любые отзывы, исправления или улучшения будут оценены.