ASP.NET MVC - динамическая авторизация

Я создаю простую CMS, в которой роли устанавливаются динамически в панели администратора. Таким образом, существующий способ авторизации метода контроллера, добавив [Authorize(Roles="admin")], например, уже недостаточно. Связь роли-действия должна храниться в базе данных, чтобы конечные пользователи могли легко давать/принимать разрешения для других пользователей в панели администратора. Как это реализовать?

Ответы

Ответ 1

Если вы хотите взять под контроль процесс авторизации, вы должны подклассы AuthorizeAttribute и переопределить AuthorizeCore. Затем просто украсьте свои контроллеры своим CmsAuthorizeAttribute вместо стандартного.

public class CmsAuthorizeAttribute : AuthorizeAttribute
{
    public override virtual bool AuthorizeCore(HttpContextBase httpContext)
    {
        IPrincipal user = httpContext.User;
        IIdentity identity = user.Identity;

        if (!identity.IsAuthenticated) {
            return false;
        }

        bool isAuthorized = true;
        // TODO: perform custom authorization against the CMS


        return isAuthorized;
    }
}

Недостатком этого является то, что у вас не будет доступа к введенному ctor-IoC, поэтому вам придется запрашивать любые зависимости из контейнера напрямую.

Ответ 2

Это именно то, что делает членство/членство в ASP.NET для вас. И он работает с атрибутом Authorize.

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

public MyAuthorizeAttribute : ActionFilterAttribute
{
    public string MyRole { get; set; }

    public void OnActionExecuting(ControllerContext context)
    {
        if (!(bool)Session["userIsAuthenticated"])
        {
            throw new AuthenticationException("Must log in.");
        }

        if (!Session["userRoles"].Contains(MyRole))
        {
            throw new AuthenticationException("Must have role " + MyRole);
        }
    }
}

Ответ 3

Роль - действие должно быть хранится в базе данных

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