Как правильно добавить свои свойства в custom IIdentity ASP.NET (OWIN)?

Добрый день! Прошу помощи в вопросе построения авторизации/аутентификации в приложении без использования ASP.NET Identity, но с использованием OWIN.

В приложении на ASP.NET MVC 5 есть метод LogIn:
[HttpPost]
public ActionResult LogIn(LoginVM loginVM)
{
	try
	{
		if (!ModelState.IsValid)
		{
			return View(loginVM);
		}

		var user = userService.GetUser(loginVM.Email, loginVM.Password);

		if (user == null) {
			// TODO: Выводить сообщение - Неверный логин или пароль
			return View(loginVM);
		}
		
		var claims = new List<Claim>();
		claims.Add(new Claim(ClaimTypes.NameIdentifier, user.UserId));
		// Также мне нужно добавить в клеймы ряд данных
		claims.Add(new Claim("Firstname", user.FirstName));
		claims.Add(new Claim("Secondname", user.SecondName));
		claims.Add(new Claim("Lastname", user.LastName));
		claims.Add(new Claim("SomeId", user.SomeId));
		claims.Add(new Claim("OneMoreId", user.SomeId));
		
		var identity = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);

		AuthenticationManager.SignIn(new AuthenticationProperties()
		{
			IsPersistent = loginVM.RememberMe,
			ExpiresUtc = DateTime.UtcNow.AddDays(7)
		}, identity);

		return RedirectToAction("Index", "Home");
	}
	catch (Exception ex)
	{
		return ErrorInternal(ex);
	}
}


В нем мы ищем пользователя с помощью собственного userService, и в случае успешного поиска авторизуем пользователя с помощью механизма OWIN, записывая при этом дополнительные данные Firstname, SomeId и.т.п.

Честно прочитав все мануалы, у меня остались вопросы:

1) Как переопределить IPrincipal/IIdentity таким образом, чтобы добавить свои поля и методы для вызова их в представлениях и контроллерах?
public class SomeController : BaseController
{
	public ActionResult Index()
	{
		ViewBag.UserName = User.Identity.SomeId; // Которые я записывал к Claims
		return View();
	}
}


и где лучше переопределять HttpContext.Current.User = CustomUser (CustomIPrincipal), в
атрибуте AuthorizeAttribute, метод - AuthorizeCore, или в методе PostAuthenticateRequest?

2) Второй вопрос связан с ролями. Допустим есть метод сервиса userService.Roles(int userId) возвращающий список ролей пользователя по идентификатору. В какой момент нужно записывать роли?

1 - Записывать в клеймы при авторизации? (метод LogIn описанный выше). Но в таком случае, если пользователю будут выданы новые роли уже после авторизации, они ведь доступны не будут?

2 - Записывать их на каждой странице в CustomPrincipal, к примеру в атрибуте AuthorizeAttribute или где-то в другом месте?

Чтобы в любом месте контроллера или представления можно было вызвать метод - User.InRoles("Admin, SuperAdmin"), к примеру).

Очень нужна консультация в этих вопросах!
Заранее благодарю за любую помощь!
  • Вопрос задан
  • 1148 просмотров
Пригласить эксперта
Ответы на вопрос 2
@dmitryKovalskiy
программист средней руки
По первому вопросу есть решение следующее(костыльное на мой взгляд, но бывало и хуже) - унаследоваться от BaseController и создать свой BaseController. В него можно добавить свойство CurrentUser(например), возвращающее ваш класс реализующий и расширяющий IPrincipal. А свойство в свою очередь должно быть реализовано как приведение User c типом IPrincipal к вашему классу.
Ответ написан
RouR
@RouR
var user = HttpContext.Current.GetOwinContext().Authentication.User;

            if (user != null)
            {
                IList<Claim> claims = user.Claims.ToList();

                Claim clientIdClaim = claims.FirstOrDefault(x => x.Type == "SomeId");

                if (clientIdClaim != null)
                {
                    string clientId = clientIdClaim.Value;
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы