Не публикуйте ответы и решения в обновленном вопросе. Положи их сюда в ответе !!!
трял на решении, которое я хотел бы предоставить в основном приложении 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, которая может использовать такие вещи, как проверка бизнес-логики. Довольно приятные вещи, хотя авторам действительно нужно больше примеров, чтобы помочь нам быстрее добраться до мяса. В любом случае, надеюсь, что это поможет будущим разработчикам, ищущим подобное решение.