Identity 2.0: создание пользовательского ClaimsIdentity, например: User.Identity.GetUserById<int>(int id) для проверки каждого запроса
Смотрите этот похожий вопрос: Нужно получить доступ к другим свойствам пользователя в User.Identity
Я хотел бы создать собственные методы аутентификации для использования со своими представлениями Razor, которые обеспечивают легкий доступ IdentityUser
свойства, относящиеся к объекту User.Identity, но я не уверен, как это сделать. Я хочу создать несколько пользовательских расширений, похожих на User.Identity.GetUserName()
, User.Identity.GetUserById()
и т. д.... вместо использования этого метода ViewContextExtension. Мой тип аутентификации в настоящее время является типом по умолчанию DefaultAuthenticationTypes.ApplicationCookie
из шаблона VS2013 MVC5. Как заявил Shoe, мне нужно вставить эту заявку после того, как пользователь войдет в систему.
Мои вопросы:
Как и где вы создаете пользовательское утверждение, которое имеет выходной параметр this IIdentity
под IPrincipal?
Это позволило бы мне получить доступ к свойствам пользователя через CookieAuthentication в представлении для сущностей в настройке DDD, где у меня есть несколько DbContexts в одном приложении с использованием Identity 2.0. В конечном итоге я буду использовать WebAPI, но сейчас я хочу сделать его как можно более простым. Я нашел эти вопросы и ответы, но они предназначены для веб-форм с использованием билетов. Не уверен, что разница между билетами и токенами тоже?
Это текущий подход, который использует ViewContext
с базового контроллера:
Посмотреть:
@using Microsoft.AspNet.Identity
@using Globals.Helpers
@using Identity //custom Identity for Domain
@using Microsoft.AspNet.Identity.Owin
@if (Request.IsAuthenticated)
{
var url = @ViewContext.BaseController().GetAvatarUrlById(User.Identity.GetUserId<int>());
//...
}
BaseController.cs
public string GetAvatarUrlById(int id)
{
var user = UserManager.FindById(id);
return "../../" + user.ImageUrl;
}
Extensions.cs
public static class ViewContextExtension
{
public static BaseController BaseController(this ViewContext view)
{
var baseController = (BaseController)view.Controller;
return baseController;
}
}
Что я ищу, но где и как?
Посмотреть:
<img src="@User.Identity.GetAvatarUrl()" alt="User.Identity.GetAvatarUrl()" />
РЕШЕНИЕ
Я просто отредактировал файл Extension.cs и использовал наследование для базового контроллера, который используется для _LoginPartial.cshtml, и отредактировал ViewContextExtension
учебный класс:
#region ViewContextExt
public static class ViewContextExtension
{
public static BaseController BaseController(this ViewContext view)
{
var baseController = (BaseController)view.Controller;
return baseController;
}
public static string GetAvatarUrl(this IIdentity identity)
{
return ((ClaimsIdentity)identity).Claims.First(c => c.Type == "AvatarUrl").Value;
}
}
}
endregion
2 ответа
IIdentity
объект в MVC будет выданным токеном, который соответствует личности пользователя. Это отличается от любого объекта или метода, который вы используете на сервере, который представляет пользователя (скажем, User
учебный класс). Если вы хотите использовать личность пользователя для получения пользовательского значения, вам нужно поместить его в объект их утверждений (т. Е. Маркер удостоверения) при входе в систему (или в другой момент времени).
Вы можете добавить претензию в любое время, указав личность пользователя.
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
identity.AddClaim(new Claim("PhoneNumber", "123-456-7890"));
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
Когда вы добавили это требование в их токен, вы можете получить его, используя метод расширения, подобный этому...
public static string GetPhoneNumber(this IIdentity identity)
{
return ((ClaimsIdentity)identity).FindFirstValue("PhoneNumber");
}
бритва
@using MyProject.Web.Extensions
<img src="@User.Identity.GetPhoneNumber()" />
Я на самом деле нашел решение, используя ответ на этот SO-вопрос от LukeP, но, как отмечает Шу, это было до MVC5, и мы могли бы вместо этого просто подать заявку.
Я сделал следующие изменения:
interface IDomainPrincipal : IPrincipal
{
int Id { get; set; }
string UserName { get; set; }
string AvatarUrl { get; set; }
}
public class DomainPrincipal : IDomainPrincipal
{
public IIdentity Identity { get; private set; }
public bool IsInRole(string role) { return false; }
public DomainPrincipal(string email)
{
this.Identity = new GenericIdentity(email);
}
public int Id { get; set; }
public string UserName { get; set; }
public string AvatarUrl { get; set; }
}
Тогда я использовал @User.Id, @User.UserName, @User.AvatarUrl
в моих @Razor Views соответственно