Аутентификация пользователя по идентификатору, записанному в базе данных

#c# #asp.net-mvc

#c# #asp.net-mvc

Вопрос:

У меня следующая проблема: у меня есть модель событий, которая содержит данные о событии и организаторе (пользователь, который его создал — идентификатор пользователя). Я хочу сделать возможность редактировать / удалять это событие только создателем. Я не знаю, как сравнить идентификатор пользователя из базы данных с идентификатором реального пользователя, который хочет совершить действие.

Должен ли я добавить авторизацию в методы редактирования / удаления в контроллере модели событий или есть другой способ проверить этот идентификатор?

EventsModelController:

         [HttpPost]
        public async Task<IActionResult> Index(string placeString, string nameString, DateTime data, DateTime time)
        {
            if(HttpContext.User.Identity.IsAuthenticated) ViewBag.userID = HttpContext.User.Identity.Name.ToString();
            var events = from e in _context.EventsModel
                         select e;
            return View(await events.ToListAsync());
        }

        [HttpPost]
        [Authorize]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Create([Bind("id,event_type,date,place,name,hour,tickets,tickets_per_person,organisator")] EventsModel eventsModel)
        {
            var userID = HttpContext.User.Identity.Name;
            eventsModel.organisator = userID;
            if (ModelState.IsValid)
            {
                _context.Add(eventsModel);
                await _context.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
            }
            return View(eventsModel);
        }
  

Я использую ViewBag для отображения параметров удаления / удаления (просмотр индекса):

              <td>
                @if (ViewBag.userID == item.organisator)
                 {
                    <a asp-action="Edit" asp-route-id="@item.id">Edit</a> 
                 }
                | <a asp-action="Details" asp-route-id="@item.id">Details</a> |
                @if (ViewBag.userID == item.organisator)
                 {
                    <a asp-action="Delete" asp-route-id="@item.id">Delete</a>
                 }
            </td>
  

На данный момент только создатель может видеть опции Редактировать и удалять в списке событий, но у всех есть доступ к этим методам.

Обновить

Мое окончательное решение: я добавил метод с именем «getUser» в EventsModel. Когда пользователь хочет вызвать метод редактирования или удаления — я проверяю текущий идентификатор пользователя на тот, который записан в object.

Фрагмент EventsModelsController:

         [Authorize]
        public async Task<IActionResult> Edit(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }
            var eventsModel = await _context.EventsModel.FindAsync(id);
            if (eventsModel.getUser() != HttpContext.User.Identity.Name.ToString())
            {
                return RedirectToAction(nameof(Index));
            }
            if (eventsModel == null)
            {
                return NotFound();
            }
            return View(eventsModel);
        }
  

Комментарии:

1. Почему вы не можете просто проверить идентификатор «организатора»?

2. Да, я проверяю это, но я хочу полностью отключить доступ к этим методам. Если я проверяю идентификатор создателя, у меня есть доступ к этим методам — я вижу окно редактирования, но изменения не будут сохранены.

3. Да, я имел в виду в контроллере. Вы даже можете сделать это промежуточным продуктом, хотя я бы не рекомендовал этот вариант.

Ответ №1:

Простой ответ: есть много способов сделать это. Это зависит от того, как вы хотите, чтобы выглядело ваше представление, но если вы просто хотите ограничить маршрут, вы можете создать роль для этой аутентификации, например

 [Authorize(Roles = "organisator")]
  

Промежуточное программное обеспечение, также может быть использовано здесь. Вы должны иметь возможность просто использовать промежуточное средство аутентификации, добавив используемую политику и обработчик для проверки контекста, чтобы узнать, является ли пользователь организатором указанного события. Но, если ваш проект не позволяет этого, пользовательский может достичь того же эффекта.

  services.AddAuthorization(options =>
        {
            options.AddPolicy("PolicyOrganisator", policy =>...);
        });
  

…Hanlder

 if (context.User.userID == context.Request... ) 
{
    context.Succeed();
}
  

Вы также можете просто проверить контроллер, как вы упоминаете в своих вопросах. Добавьте дополнительные данные в свою модель, чтобы указать, может или не может получить этот пользователь.

 calss EventsModel {
 ...
 bool canEdit { get => userID == item.organisator; } 
}
  

Если это единственный маршрут, который вы пытаетесь ограничить, то я не вижу, что плохого в добавлении оператора if в верхней части метода, чтобы проверить, следует ли перенаправлять. Я добавил ссылки внизу страницы, потому что примеры будут меняться в зависимости от того, как вы настраиваете свой проект.

https://learn.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-2.2

https://learn.microsoft.com/en-us/aspnet/core/security/authorization/roles?view=aspnetcore-2.2

https://learn.microsoft.com/en-us/dotnet/standard/attributes/writing-custom-attributes

Комментарии:

1. Да, но если у меня есть x пользователей, роли имеют значение? Поскольку, например, Пользователь1 создал Event1 и Event3, Пользователь2 создал Event2. Если у обоих есть организатор ролей, оба могут редактировать все события?

2. Я понимаю вашу точку зрения, в этом случае вы даже можете создать пользовательский атрибут и передать идентификатор

3. Потрясающе, вы можете задать мне любые другие вопросы, которые у вас есть, прежде чем сделать еще один пост. Пожалуйста, отметьте мой пост как ответ и отправьте свой фрагмент окончательного решения.