Авторизация ASP.NET Core не работает для вложенных ролей

Я реализовал управление доступом на основе ролей (RBAC) в проекте ASP.NET Core. Я требую, чтобы пользователь принадлежал хотя бы к одной роли Active Directory, в зависимости от того, в какой среде развернут код (DEV, STAGING, PROD). Код ниже работает. Однако вместо того, чтобы использовать несколько ролей для каждой среды, теперь мне необходимо использовать одну «вложенную»/сгруппированную/иерархическую роль, т.е. новая роль объединяет другие роли. Использование новой роли AD больше не работает. Я подтвердил, что являюсь участником новой роли, но получаю сообщение об ошибке авторизации. Я не могу найти ничего в Интернете, чтобы обсудить, можно ли использовать сгруппированные роли в ASP.NET Core.

public void ConfigureServices(IServiceCollection services)
{
    try
    {
        services.AddAuthentication(IISDefaults.AuthenticationScheme);
        services.AddMvc().AddApplicationPart(typeof(ProcessController).Assembly).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        services.AddRequestScopingMiddleware(() => _scopeProvider.Value = new Scope());
        services.AddCustomControllerActivation(Resolve);
        services.AddCustomViewComponentActivation(Resolve);

        services.AddAuthorization(options =>
        {
            var policyBuilder = new AuthorizationPolicyBuilder().RequireAuthenticatedUser();
            switch (HostingEnvironment.EnvironmentName)
            {
                case "Development":
                    policyBuilder.RequireRole("roleA", "roleB");
                    //policyBuilder.RequireRole("roleAandB");//this doesn't work
                    break;
                case "Staging":
                    policyBuilder.RequireRole("roleC", "roleD");
                    break;
                case "Production":
                    policyBuilder.RequireRole("roleE", "roleF");
                    break;
                default:
                    policyBuilder.RequireRole("roleG");
                    break;
            }

            options.AddPolicy("Environment", policyBuilder.Build());
        });

    }
    catch (Exception e)
    {
        _logger.Error(e, "Unhandled exception");
        throw;
    }
}

[Authorize(Policy = "Environment")]
public class ProcessController : ControllerBase 
{
    ...
}

Как использовать вложенные роли в авторизации ASP.NET Core?


person Lostinfrance    schedule 18.11.2019    source источник
comment
Обычно роли Active Directory на самом деле представляют собой группы в AD. Итак, есть ли у вас в AD группы с именами roleA, roleB и т. д.?   -  person Gabriel Luci    schedule 18.11.2019
comment
Я проверил, и вы правы. roleA, roleB и roleAandB — все это группы, а не роли с точки зрения AD.   -  person Lostinfrance    schedule 18.11.2019
comment
Так что в этом случае это должно работать, пока группы roleA и roleB добавляются в группу roleAandB.   -  person Gabriel Luci    schedule 18.11.2019


Ответы (1)


То, что в ASP.NET называется «ролями», соответствует группам в Active Directory. Таким образом, проверка того, есть ли у пользователя AD роль, на самом деле проверяет, входит ли пользователь в группу.

Допустим, вы хотите предоставить «опытным пользователям» доступ к определенной части веб-сайта. Вы должны создать группу в AD с именем MyAppPowerUsers и использовать ее в качестве роли в своем приложении:

policyBuilder.RequireRole("MyAppPowerUsers");

Затем вы добавляете всех, кого считаете «опытными пользователями», в эту группу в AD. Например, если вы хотите предоставить всем менеджерам и руководителям групп доступ к этой части вашего сайта для «опытных пользователей», вы создаете группы с именами Managers и TeamLeads и добавляете их в MyAppPowerUsers.

В этом случае любой пользователь, который является членом Managers или TeamLeads, будет считаться членом MyAppPowerUsers.

Итак, идея в том, что по большей части вы:

  • Создайте группу, названную в честь роли в вашем приложении.
  • Создайте группы для должностных инструкций. Возможно, они у вас уже есть, например, в виде списков рассылки (при условии, что эти списки рассылки имеют «Тип группы» «Безопасность»)
  • Добавьте группы описания работы к ролям

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

person Gabriel Luci    schedule 19.11.2019
comment
Как насчет ситуации, когда вы находитесь в roleAandB, но применяете атрибут Authorize как: roleA. Кажется, это не работает, как я мог себе представить, но работает ли это так, как задумано, по вашему мнению/пониманию? - person askrich; 03.12.2019
comment
Это был бы противоположный сценарий. Чтобы это работало, roleAandB должен быть членом roleA. Возможно, было бы понятнее, если бы я использовал имена для ролей вместо A и B. Я обновил свой ответ. - person Gabriel Luci; 03.12.2019
comment
Теперь это яснее, хотя раньше это имело смысл. Я говорю о роли CanSeePerformance, членами которой будут Managers и TeamLeads, однако затем я стану членом Managers. Мое намерение состояло в том, чтобы сделать вывод, что у меня есть CanSeePerformance; мы говорим, что это невозможно? - person askrich; 04.12.2019
comment
Это сработает. Если вы являетесь членом группы Managers, а Managers является членом CanSeePerformance, и вы предоставляете разрешения CanSeePerformance, то это будет означать, что у вас есть разрешение CanSeePerformance. Имейте в виду, что все эти группы AD должны иметь групповой тип безопасности. Это не будет работать, если тип группы — список рассылки. - person Gabriel Luci; 04.12.2019