Я застрял в решении, которое я хотел бы предоставить в основном приложении asp.net mvc. Я хотел бы предложить решение стандартного User, Roles, Permissions в веб-приложении, используя новый подход на основе требований.Пользователи Роли Разрешения с использованием идентификатора ядра ASP.NET 3
Я слежу за логикой Бен Фостера здесь (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: После создания своих пользователей, ролей и претензий (и связывая их), мне нужно, чтобы зарегистрировать «Политики» в классе Startup.cs метода Confirgure Services. Это позволяет мне отображать претензии к политике или политикам.
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 в качестве второго параметра, а также имя «Политика», к которому относится связанное с ним требование. С тех пор я исправил его ниже.
@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. Если у пользователя нет этой претензии, назначенной на их роль, тогда проверка политики, которая возвращает true или false, не покажет кнопку для добавления роли. Эта же логика проверки политики может быть добавлена к контроллеру или любому другому ресурсу через DI благодаря новому промежуточному программному обеспечению .net core DI. Благодаря этому упражнению я узнал силу Identity 3, которая может использовать такие вещи, как проверка бизнес-логики. Довольно сладкий материал, хотя писателям действительно нужно больше примеров, чтобы помочь нам быстрее добраться до мяса. Во всяком случае, надеюсь, что это поможет будущим разработчикам искать аналогичное решение.
Поскольку вы работаете с ролями, вы можете найти эту статью полезной в пользу использования объектов привилегий над проверками ролей: http://ardalis.com/favor-privileges-over-role-checks – ssmith