ASP.NET MVC Attribute позволяет пользователю редактировать собственный контент - программирование
Подтвердить что ты не робот

ASP.NET MVC Attribute позволяет пользователю редактировать собственный контент

У меня есть метод контроллера под названием Edit, в котором пользователь может редактировать данные, которые они создали так...

public ActionResult Edit(int id)
{
    Submission submission = unit.SubmissionRepository.GetByID(id);
    User user = unit.UserRepository.GetByUsername(User.Identity.Name);

    //Make sure the submission belongs to the user
    if (submission.UserID != user.UserID)
    {
        throw new SecurityException("Unauthorized access!");
    }

    //Carry out method
}

Этот метод работает отлично, но немного путаться в каждом методе редактирования контроллера. Каждая таблица всегда имеет UserID, поэтому мне было интересно, есть ли более простой способ автоматизировать это с помощью атрибута [Authorize] или какого-либо другого механизма, чтобы сделать код чистым.

4b9b3361

Ответ 1

Да, вы можете достичь этого с помощью настраиваемого атрибута Authorize:

public class MyAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var authorized = base.AuthorizeCore(httpContext);
        if (!authorized)
        {
            return false;
        }

        var rd = httpContext.Request.RequestContext.RouteData;

        var id = rd.Values["id"];
        var userName = httpContext.User.Identity.Name;

        Submission submission = unit.SubmissionRepository.GetByID(id);
        User user = unit.UserRepository.GetByUsername(userName);

        return submission.UserID == user.UserID;
    }
}

а затем:

[MyAuthorize]
public ActionResult Edit(int id)
{
    // Carry out method
}

и предположим, что вам нужно подавать этот экземпляр представления, который мы ввели в пользовательский атрибут в качестве параметра действия, чтобы не ударить по базе данных еще раз, вы могли бы сделать следующее:

public class MyAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var authorized = base.AuthorizeCore(httpContext);
        if (!authorized)
        {
            return false;
        }

        var rd = httpContext.Request.RequestContext.RouteData;

        var id = rd.Values["id"];
        var userName = httpContext.User.Identity.Name;

        Submission submission = unit.SubmissionRepository.GetByID(id);
        User user = unit.UserRepository.GetByUsername(userName);

        rd.Values["model"] = submission;

        return submission.UserID == user.UserID;
    }
}

а затем:

[MyAuthorize]
public ActionResult Edit(Submission model)
{
    // Carry out method
}

Ответ 2

Я бы предложил вам вывести логику из action/controller и построить класс домена для обработки этой логики.

Методы действий должны действительно иметь дело только с получением данных и отправкой данных в представление. Вы могли бы создать что-то общее, чтобы справиться с вашими потребностями, но также будете следовать единому принципу ответственности.

public class AuthorizedToEdit 
{
     protected override bool AuthorizeCore(string user, int itemId)
     {
         var userName = httpContext.User.Identity.Name;

         var authUsers = SubmissionRepository.GetAuthoriedUsers(itemId);

         return authUsers.Contains(user);
     }
}

Это также даст вам возможность гибкости позже, чтобы позволить что-то вроде пользователей admin

Ответ 3

Я рекомендую читать на AuthorizeAttribute (см. здесь). Кроме того, вы видели сообщение this? В нем рассказывается, как переопределить внутренние атрибуты аутентификации и как использовать IPrincipal и IIdentity.