Подтвердить что ты не робот

MVC 3 динамическое разрешение нескольких ролей и пользователей

Недавно я занимался разработкой MVC 3, но с тех пор у меня есть опыт работы как на С#, так и на ASP.NET. Поэтому я начну с того, что я пытаюсь выполнить. Я разработал небольшой сайт для размещения статей. Я внедрил управление сайтом на основе SQLServer на сайт. Теперь я хочу создать систему учетных данных, которая ограничивает и позволяет правильным пользователям создавать, удалять и обновлять статьи. Для этого есть одно простое решение: сделать это следующим образом:

[Authorize(Roles="Admin")]
    public ActionResult UpdateArticle(ArticleModel model, int articleid)
    {
        return View();
    }

Теперь это действительно просто. Я просто говорю, что только членам, находящимся в роли "Admin", разрешено обновлять статью. Но это только статично. Поэтому я создал таблицу учетных данных в моей базе данных, которая в конце говорит мне, что "Статья 5 может быть отредактирована ролями 1,2,3 и 4 и пользователями A, b и C". Все идет нормально. Но как я могу реализовать это с помощью разрешения Authorize?

Я хотел бы сделать что-то вроде этого:

[Authorize(getAuthorizedusers("update",this.articleid))]

где getAuthorizedusers возвращает, какие пользователи и роли имеют право обновлять статью с переданной ей статьей.

Итак, у меня есть (по крайней мере) две проблемы: -Удаление метода авторизации для приема нескольких пользователей и ролей. -Пассирование поставляемого изделия, которое было отправлено методу UpdateArticle, методу getAuthorizedusers.

4b9b3361

Ответ 1

Вы можете создать свой собственный пользовательский атрибут, который наследует от AuthorizeAttribute и переопределить метод OnAuthorize, чтобы сделать то, что вам нужно.

Это должно помочь вам:

public class ArticleAuthorizeAttribute : AuthorizeAttribute
{
    public enum ArticleAction
    { 
        Read,
        Create,
        Update,
        Delete
    }

    public ArticleAction Action { get; set; }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);

        //do custom authorizization using Action and getting ArticleID 
        //from filterContext.HttpContext.Request.QueryString or
        //filterContext.HttpContext.Request.Form
    }
}

Использование будет выглядеть так:

[ArticleAuthorize(Action=ArticleAuthorizeAttribute.ArticleAction.Update)]

Изменить: посмотрев на это немного больше, похоже, что вы не можете передать this.articleID в атрибут. Однако у вас есть доступ к параметрам из filterContext.HttpContext.Request через свойство QueryString или свойство Form, в зависимости от того, как вы передаете значения. Я обновил образец кода соответствующим образом.

Более полный пример можно найти здесь

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

        var allowedUsers = new List<string>();
        //populate allowedUsers from DB

        If (User.IsInRole("Update") || allowedUsers.Contains(User.Identity.Name))
        {
            //authorized
        }

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

Ответ 2

Здесь намного проще выполнить одно и то же:

[Authorize]
public ActionResult UpdateArticle(ArticleModel model, int articleid)
{
    // if current user is an article editor
    return View();
    // else
    return View("Error");
}

Ответ 3

Я получил его работу, как мне хотелось, когда я переопределил метод AuthorizeCore и разрешил способ, которым я хочу.

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        if (httpContext == null)
        {
            throw new ArgumentNullException("httpContext");
        }

        IPrincipal user = httpContext.User;
        if (!user.Identity.IsAuthenticated)
        {
            return false;
        }

        if ((_usersSplit.Length > 0 && !_usersSplit.Contains(user.Identity.Name, StringComparer.OrdinalIgnoreCase)) && (_rolesSplit.Length > 0 && !_rolesSplit.Any(user.IsInRole)))
        {
            return false;
        }

        return true;
    }