Не публикуйте ответы и решения в обновленном вопросе. Положи их сюда в ответе !!!

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

Я следовал логике Бена Фостера здесь (http://benfoster.io/blog/asp-net-identity-role-claims). В приведенном ниже коде (демонстрационное качество) я иллюстрирую свою методологию, которую я прокомментирую, чтобы помочь показать мое быстрое и грязное тестовое решение.

У меня есть проблема, что это не работает.

// ПРИМЕЧАНИЕ: я нашел ошибку и прокомментирую, где я ошибся, для будущих пользователей, которые ищут подобное решение.

Seed Class: Это быстрое и грязное решение для заполнения базы данных двумя новыми пользователями, двумя ролями и некоторыми претензиями на одну из ролей. Я сделал это в качестве тестового приложения, чтобы изучить подход на основе утверждений к управлению авторизацией для моего приложения. Мое полное решение предоставит каждому Арендатору возможность создавать свои собственные роли через пользовательский интерфейс, связывать 1 или несколько утверждений с ролями, а затем назначать роль пользователю. Я хотел предоставить арендаторам возможность управлять своими пользователями и что они могут или не могут делать. Это простая реализация подхода, основанного на утверждениях, поскольку утверждения имеют гораздо больше возможностей, чем отношения 1: 1 с политиками.

public class DbInitializer
{
    private ApplicationDbContext _context;
    private RoleManager<ApplicationRole> _roleManager;
    private UserManager<ApplicationUser> _userManager;

    public DbInitializer(ApplicationDbContext context,RoleManager<ApplicationRole> roleManager, UserManager<ApplicationUser> userManager)
    {
        _roleManager = roleManager;
        _userManager = userManager;
        _context = context;

    }

    public async Task Initialize()
    {
        //RoleManager<IdentityRole> roleManager = new RoleManager<IdentityRole>();
        //UserManager<ApplicationUser> userManager = new UserManager<ApplicationUser>();

        _context.Database.EnsureCreated();

        // Look for any students.
        if (!_context.Users.Any())
        {
            //create user and admin role

            ApplicationUser adminUser = new ApplicationUser();

            adminUser.Email = "[email protected]";
            adminUser.UserName = "Admin";

            var result = await _userManager.CreateAsync(adminUser, "Password-1");

            var newAdminUser = await _userManager.FindByEmailAsync(adminUser.Email);

            ApplicationRole adminRole = new ApplicationRole();

            adminRole.Name = "Admin";
            adminRole.Description = "This is the admin role.";

            await _roleManager.CreateAsync(adminRole);

            await _roleManager.AddClaimAsync(adminRole, new Claim("Can add roles", "add.role"));
            await _roleManager.AddClaimAsync(adminRole, new Claim("Can delete roles", "delete.role"));
            await _roleManager.AddClaimAsync(adminRole, new Claim("Can edit roles", "edit.role"));

            await _userManager.AddToRoleAsync(newAdminUser, adminRole.Name);

            //create user and basic role

            ApplicationUser basicUser = new ApplicationUser();

            basicUser.Email = "[email protected]";
            basicUser.UserName = "Basic";

            var resultBasic = await _userManager.CreateAsync(basicUser, "Password-1");

            var newBasicUser = await _userManager.FindByEmailAsync(basicUser.Email);

            ApplicationRole basicRole = new ApplicationRole();

            basicRole.Name = "Basic";
            basicRole.Description = "This is the basic role.";

            await _roleManager.CreateAsync(basicRole);

            //await _roleManager.AddClaimAsync(basicRole, new Claim("Can add roles", "add.role"));
            //await _roleManager.AddClaimAsync(basicRole, new Claim("Can delete roles", "delete.role"));
            //await _roleManager.AddClaimAsync(basicRole, new Claim("Can edit roles", "edit.role"));

            await _userManager.AddToRoleAsync(newBasicUser, basicRole.Name);

            await _context.SaveChangesAsync();
        }

    }
 }
}

Startup.CS: После создания моих пользователей, ролей и утверждений (и их связывания) мне нужно было зарегистрировать «Политики» в методе Confirgure Services класса Startup.cs. Это позволяет мне сопоставить претензии с политикой или политиками.

 public void ConfigureServices(IServiceCollection services)
    {
        // Add framework services.
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

        services.AddIdentity<ApplicationUser, ApplicationRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();


        services.AddAuthorization(options =>
        {
            options.AddPolicy("Add Role",
                policy => policy.RequireClaim("Can add roles", "add.role"));
            options.AddPolicy("Edit Role",
                policy => policy.RequireClaim("Can edit roles", "edit.role"));
            options.AddPolicy("Delete Role",
                policy => policy.RequireClaim("Can delete roles", "delete.role"));
        });

        services.AddMvc();

        services.AddTransient<DbInitializer>();

        // Add application services.
        services.AddTransient<IEmailSender, AuthMessageSender>();
        services.AddTransient<ISmsSender, AuthMessageSender>();
    }

Представление: в моем случае использования я хотел ограничить кнопку «Добавить роль» для любого пользователя, у которого нет утверждения «Может добавлять роли», связанного с назначенной ему ролью. Остальная часть кода представления не имеет отношения. Проблема, с которой я столкнулся, заключается в том, что я передал имя заявки в AuthorizationService.AuthorizeAsync в качестве второго параметра по сравнению с именем «Policy», с которым связана заявка. С тех пор я исправил это ниже.

@model IEnumerable<ApplicationRoleListViewModel>
@using HailMarry.Models
@using Microsoft.AspNetCore.Authorization
@inject IAuthorizationService AuthorizationService

<br />
<div class="top-buffer"></div>
<div class="panel panel-primary">
<div class="panel-heading panel-head">Application Roles</div>
<div class="panel-body">
    <div class="btn-group">

         //Mistake
        //@if (await AuthorizationService.AuthorizeAsync(User, "Can add roles"))
         //Fix
         @if (await AuthorizationService.AuthorizeAsync(User, "Add Role"))
        {
            <a id="createRoleButton" asp-action="AddRole" asp-controller="ApplicationRole" class="btn btn-primary">
                <i class="glyphicon glyphicon-plus"></i>  Add Role
            </a>
        }
....

Конечный результат: у меня есть пользователь «[email protected]», которому назначена роль «Администратор», у которого есть утверждение «Можно добавлять роли». Роль может иметь любое количество требований. Я создал Политику, которая имеет то же утверждение «Может добавлять роли», что я проверил в представлении через инъецируемую службу IAuthorizationService AuthorizationService. Если у пользователя нет этой заявки, назначенной для его роли, то проверка политики, которая возвращает истину или ложь, не покажет кнопку для добавления роли. Эта же логика проверки политики может быть добавлена ​​к контроллеру или любому другому ресурсу через DI благодаря новому промежуточному программному обеспечению DI ядра .net. Благодаря всему этому упражнению я узнал всю мощь Identity 3, которая может использовать такие вещи, как проверка бизнес-логики. Довольно приятные вещи, хотя авторам действительно нужно больше примеров, чтобы помочь нам быстрее добраться до мяса. В любом случае, надеюсь, что это поможет будущим разработчикам, ищущим подобное решение.

Ответы на вопрос(1)

Ваш ответ на вопрос