ASP. Net MVC 5: Лучший способ разработать систему ролевого доступа для веб-продукта - PullRequest
1 голос
/ 09 июля 2020

Мне, возможно, придется разработать систему ERP, которая не будет публиковаться c на веб-сайте, а будет использоваться различными пользователями конкретной c организации. Я ищу лучшую идею для разработки области системы разрешений пользователей, где администратор назначает доступ к ролям и назначает эти роли пользователю. Ролевой пользователь может или не может получить доступ к веб-страницам.

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

предположим, что на моем сайте будут страницы, связанные с кадрами, продажами и со счетами. Таким образом, любой пользователь не может получить доступ к страницам, связанным с HR или Account, Purchase. способ, которым администратор предоставляет права таким образом, чтобы пользователь мог получить доступ к области.

предположим, что на первой странице администратор сохранит все имя контроллера и имя их действия в главной таблице

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

Say HR Controller

  1) PayslipView Action

  2) Payslip Edit Action

et c

, поэтому администратор сначала создаст несколько ролей, таких как HR , Учетные записи, Покупка и продажа и т. Д. c.

сначала администратор. Выберите роли из раскрывающегося списка .

ниже. Я покажу название разумного действия контроллера. admin просто отметьте имя контроллера несколькими именами действия и сохраните эту информацию в db. где я сохраню идентификатор роли и идентификатор контроллера, идентификатор действия.

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

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

, потому что я не хочу жестко кодировать роли с таким действием

[Authorize(Roles = "Producer")]
[Authorize(Roles = "Admin")]
public ActionResult Details(int id) {
    // Only available to users who are Producers AND Editors
}

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

public class DynamicRoleAuthorizeAttribute: AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var controller = httpContext.Request.RequestContext
            .RouteData.GetRequiredString("controller");
        var action = httpContext.Request.RequestContext
            .RouteData.GetRequiredString("action");
        // feed the roles here
        Roles = string.Join("," ,_rolesProvider.Get(controller, action));
        return base.AuthorizeCore(httpContext);
    }
}

[DynamicRoleAuthorize]
public ActionResult MyAction()
{

}

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

поэтому, пожалуйста, расскажите мне, как разработать такую ​​систему разрешений в asp. net mvc 5, который не будет зависеть от имени контроллера или имени действия. если это имя изменится, то разрешение должно работать.

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

Я ищу в Google, но не нашел хорошего решения, которому я мог бы следовать. есть множество статей о различных топах c, связанных с asp. net mvc, но это очень важная часть любого продукта, который, как я понял, мало касался моего поиска в Google.

если у кого-то есть ссылки на статьи, связанные с этим топом c, то, пожалуйста, поделитесь со мной URL-адресом для RBA C системы . если статья находится на asp. net core mvc, тогда это также поможет мне получить представление.

спасибо

Ответы [ 2 ]

1 голос
/ 10 июля 2020

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

По сути, система разрешений включает участников (обычно пользователей) и защищаемые ресурсы (например, , API). Задача состоит в том, чтобы иметь возможность назначать разрешения пользователям и проверять такие разрешения, когда пользователь вызывает API. Разрешение требуется для API может и должно быть жестко запрограммировано:

[FuncPermission("GetHrData")]
public ActionResult Details(int id) {
    // Only available to users that have GetHrData Permission
}

Затем вы определяете роли (группы пользователей) и назначаете разрешения для ролей. На мой взгляд, вам не следует жестко кодировать роль в атрибуте Authorize.

Откуда вы go отсюда?

  1. Сохраняйте свои разрешения в базе данных. Итак, по мере разработки новых функций вы добавляете новые разрешения, но ваш модуль администратора не меняется.
  2. Разработка обычных функций администратора для пользователей и групп (ролей). Предпочтительно назначать разрешения группам; не для пользователей
  3. Разработайте промежуточное ПО для авторизации, которое будет сопоставлять разрешения пользователей с разрешениями, необходимыми для доступа к определенному c API. Класс FuncPermissionAttribute является частью такого промежуточного программного обеспечения.
  4. Если возможно (то есть разрешений не так много), вы можете сохранить их как утверждения ролей в Microsoft Identity и передать их как часть заголовка. Обратите внимание, что заголовок имеет ограничение по размеру (8–16 КБ на большинстве веб-серверов); поэтому вам может потребоваться получить эти утверждения из базы данных.
  5. Пользователь может принадлежать к нескольким группам с потенциально перекрывающимися разрешениями; поэтому вам нужно «сгладить» разрешения, чтобы добиться соответствия.

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

0 голосов
/ 14 июля 2020

Я просмотрел старый проект MVC 5 и обнаружил, что это отправная точка для вас.

Я предполагаю, что каждый контроллер имеет чтение / запись / редактирование / удаление - или базовый c CRUD операции. Я создал код, который использовал отражение для просмотра проекта, и для каждого контроллера создал четыре утверждения - имя контроллера и каждое из четырех возможных действий. Я вручную создал заявки на пункты меню. Таким образом, представление может скрывать или отключать параметры меню, к которым пользователь не имеет доступа.

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

класс атрибута авторства утверждений показан ниже

[ClaimsAuthorize("InvoicesController", "Edit")]
[ValidateAntiForgeryToken]
[HttpPost]
public async Task<ActionResult> CancelInvoice(InvoiceView v)
{
    var user = _userManager.FindById(User.Identity.GetUserId());

    await _bs.CancelInvoice_Async(v, ModelState, user.Id);

    if (ModelState.IsValid)
    {
        // state saved
        return RedirectToAction("Edit", new { id = v.InvoiceId });
    }

    // not saved
    return View("Edit", v);
}




    /// <summary>
    /// Allows use of an authorisation attribute on controllers and controller methods
    /// </summary>
    public class ClaimsAuthorizeAttribute : AuthorizeAttribute
    {
        private string claimType;
        private string claimValue;
    
        /// <summary>
        /// Authorise using a claim by type (and optional value)
        /// </summary>
        /// <param name="type">The Claim Type - Usually [Controller]_[Action]</param>
        /// <param name="value">The Claim Value, usually one of Read | Edit | Create | Delete, or some other relevant value</param>
        public ClaimsAuthorizeAttribute(string type, string value = "")
        {
            this.ClaimType = type;
            this.ClaimValue = value;
        }
    
        /// <summary>
        /// Gets the Claim Type - Usually [Controller]_[Action]
        /// </summary>
        public string ClaimType { get => claimType; protected set => claimType = value; }
    
        /// <summary>
        /// Gets the Claim Value, usually one of Read | Edit | Create | Delete, or some other relevant value
        /// </summary>
        public string ClaimValue { get => claimValue; protected set => claimValue = value; }
    
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            // assume not authorised
            bool isAuthorised = false;
    
            // check user exists
            if (filterContext.HttpContext.User != null)
            {
                // get user by claim principle
                var user = filterContext.HttpContext.User as System.Security.Claims.ClaimsPrincipal;
    
                if (user != null && user.HasClaim(ClaimType, ClaimValue))
                {
                    // user has a claim of the correct type
                    isAuthorised = true;
                }
            }
    
            if (isAuthorised)
            {
                filterContext.Result = null;
                base.OnAuthorization(filterContext);
            }
            else
            {
                // we don't use 401 as this will cause a login loop :  base.HandleUnauthorizedRequest(filterContext);
                // Forbidden message will be shown
                filterContext.Result = new HttpStatusCodeResult(HttpStatusCode.Forbidden, "You are forbidden to access this resource");
            }
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...