Как использовать роли в ASP.NET Core 2.1?

Я создал тестовый проект, используя:

dotnet new razor --auth Individual --output Test

Это создает Startup.cs, который содержит:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        // This lambda determines whether user consent for non-essential cookies is needed for a given request.
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });

    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlite(
            Configuration.GetConnectionString("DefaultConnection")));

    services.AddDefaultIdentity<IdentityUser>()
        .AddEntityFrameworkStores<ApplicationDbContext>();

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

Я хочу засеять некоторые пользователи и роли. Оба пользователя и роли будут использовать один и тот же магазин (SQLite). Я использую статический класс для посева, который он вызвал из Program.

Я могу посеять пользователей, но не роли, так как выше, похоже, не вводит RoleManager.

В ASP.NET Core 2.0 используется следующее:

services.AddIdentity<IdentityUser, IdentityRole>()

Я предполагаю, что AddDefaultIdentity является новым в версии 2.1, но проблема в том, что он не вводит RoleMnager, так что мне делать?

Ответ 1

Похоже, что, наконец, Microsoft поняла, что не каждое приложение нуждается в ролях и отделяет их.

Обратите внимание, что AddDefaultIdentity объявляется как:

public static IdentityBuilder AddDefaultIdentity<TUser>(this IServiceCollection services) where TUser : class;

Таким образом, вы можете продолжить настройку параметров Identity через IdentityBuilder. Что вы хотите сделать:

services.AddDefaultIdentity<IdentityUser>().AddRoles<IdentityRole>();

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

Ответ 2

Может помочь кому-то еще: если вы добавите идентификатор asp.net через строительные леса в существующий проект, вам нужно будет отредактировать IdentityHostingStartup.cs и изменить службы там, а не в вашем классе запуска:

services.AddIdentity<AppUser, IdentityRole>()
                .AddDefaultUI()
                .AddRoles<IdentityRole>()
                .AddRoleManager<RoleManager<IdentityRole>>()
                .AddDefaultTokenProviders()
                .AddEntityFrameworkStores<authContext>();

И затем вы можете использовать диспетчер ролей в своем посеве.

Ответ 3

В дополнение к уже предоставленным ответам, несмотря на добавление .AddRoles<Identity>(), я до сих пор не мог получить авторизацию при использовании на моих контроллерах Authorize(Roles = "Administrator"). По какой-то причине утверждение роли не влияет на IsUserInRole или AuthorizeAttribute с именем роли.

Чтобы использовать роли, я бы предложил использовать один из способов ASP.NET 2.0, как показано ниже:

services.AddIdentity<IdentityUser, IdentityRole>()
            .AddDefaultUI()
            .AddDefaultTokenProviders()
            .AddEntityFrameworkStores<ApplicationDbContext>();

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

См. Эту проблему в aspnet github: Issue 1813

Ответ 4

Я также боролся с этой проблемой некоторое время назад. Я не мог делать роли для работы.

В моем проекте я использовал ASP.NET Core 2.1 (это можно исправить в 2.2, см. Ссылку), а также создал некоторые страницы.

После долгих поисков в Интернете я нашел это решение (которое также упоминалось выше в выпуске 1813)

Решение было для меня (как предложено в статье) добавить следующую строку с IUserClaimsPrincipalFactory:

        services.AddScoped<IUserClaimsPrincipalFactory<IdentityUser>, 
            UserClaimsPrincipalFactory<IdentityUser, IdentityRole>>();

        services.AddDefaultIdentity<IdentityUser>()
            .AddRoles<IdentityRole>()
            .AddRoleManager<RoleManager<IdentityRole>>()
            .AddDefaultTokenProviders()
            .AddEntityFrameworkStores<TranslatorDbContext>();