Как реализовать настраиваемый атрибут Authorize для следующего случая?

22

, поэтому у меня есть свой метод действий

[Authorize(Roles="Admin")]
public ActionResult EditPosts(int id)
{
    return View();
}

В моем случае мне нужно авторизовать администраторов, чтобы они могли редактировать сообщения, но (здесь идет крутая часть), я также должен разрешить создателю сообщения иметь возможность редактировать сообщение, которое является обычным пользователем. Итак, как я могу отфильтровать пользователя, создавшего сообщение, а также администраторов, но оставив остальных несанкционированными? Я получаю идентификатор PostEntry в качестве параметра маршрута, но после атрибута, а также атрибуты принимают только постоянные параметры, выглядит как-то очень сложно, ваши ответы высоко ценятся, Cheers!

    
задан Freeman 15.07.2012 в 19:02
источник
  • Поскольку вы можете не знать, кто создал сообщение, пока вы его не просмотрите. Возможно, было бы лучше включить эту логику после увлажнения объекта. В противном случае, если вы реализуете это как аспект, вам, возможно, придется дважды просмотреть сообщение (один раз для авторизации и один раз для редактирования). –  Davin Tryon 15.07.2012 в 19:20
  • точка хорошо поставлена, действительно, я когда-нибудь посмотрю, будет ли его идентификатор включен в запись роли и снова сделать свою логику контроллера. Любые идеи, как ударить по базе данных только один раз? –  Freeman 15.07.2012 в 19:56
  • Думая об этом немного больше, если вы используете хороший ORM и устанавливаете свой контекст перед вызовом авторизации (не уверен в этой части), тогда он должен кэшировать кеш 1-го уровня. Затем вы не должны видеть бит бит на втором гидрате. –  Davin Tryon 15.07.2012 в 22:13
  • Я действительно использую Entity Framework 4.0, но я не думаю, что он чтит что-либо. –  Freeman 16.07.2012 в 08:36

1 ответ

44

Вы можете написать собственный атрибут authorize:

public class AuthorizeAdminOrOwnerOfPostAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var authorized = base.AuthorizeCore(httpContext);
        if (!authorized)
        {
            // The user is not authenticated
            return false;
        }

        var user = httpContext.User;
        if (user.IsInRole("Admin"))
        {
            // Administrator => let him in
            return true;
        }

        var rd = httpContext.Request.RequestContext.RouteData;
        var id = rd.Values["id"] as string;
        if (string.IsNullOrEmpty(id))
        {
            // No id was specified => we do not allow access
            return false;
        }

        return IsOwnerOfPost(user.Identity.Name, id);
    }

    private bool IsOwnerOfPost(string username, string postId)
    {
        // TODO: you know what to do here
        throw new NotImplementedException();
    }
}

, а затем украсить его действие с ним:

[AuthorizeAdminOrOwnerOfPost]
public ActionResult EditPosts(int id)
{
    return View();
}
    
ответ дан Darin Dimitrov 15.07.2012 в 19:30
источник
  • Спасибо !!! Это именно то, что мне нужно !!! –  TamarG 30.07.2012 в 13:51
  • Почему // Теперь был указан id => мы не разрешаем доступ? –  Royi Namir 14.10.2014 в 11:12
  • Теперь я вижу, что вам нужно изменить: // Теперь был указан id, для которого был указан NO id .... (кажется, что если есть идентификатор, мы не разрешаем доступ) –  Royi Namir 14.10.2014 в 11:14
  • Спасибо, - прорезает шквал, который там, и получает прямо к делу! –  cyclical 16.03.2015 в 22:19
  • Это сообщение очень полезно, поскольку оно помогло мне разрешить все роли в приложении mvc, кроме роли «пользователя» для некоторого контроллера. –  Sorangwala Abbasali 28.11.2016 в 12:18