Entity framework core 创建基于角色的动态授权
我已经实现了基于身份角色的授权,但必须手动转到每个控制器/操作并单独指定Entity framework core 创建基于角色的动态授权,entity-framework-core,asp.net-core-identity,Entity Framework Core,Asp.net Core Identity,我已经实现了基于身份角色的授权,但必须手动转到每个控制器/操作并单独指定[授权(角色=”“)]扩展性非常差 我如何能够创建一个具有动态基于角色的授权的UI屏幕,其中“超级管理员”可以配置哪个角色可以访问控制器/操作 大概是这样的: 经过大量的尝试和研究,我找到了一个合适的答案:(非常感谢Mohen'mo esmp'Esmailpour) 创建2个类: public class MvcControllerInfo { public string Id => $"{AreaName}:
[授权(角色=”“)]
扩展性非常差
我如何能够创建一个具有动态基于角色的授权的UI屏幕,其中“超级管理员”可以配置哪个角色可以访问控制器/操作
大概是这样的:
经过大量的尝试和研究,我找到了一个合适的答案:(非常感谢Mohen'mo esmp'Esmailpour) 创建2个类:
public class MvcControllerInfo
{
public string Id => $"{AreaName}:{Name}";
public string Name { get; set; }
public string DisplayName { get; set; }
public string AreaName { get; set; }
public IEnumerable<MvcActionInfo> Actions { get; set; }
}
public class MvcActionInfo
{
public string Id => $"{ControllerId}:{Name}";
public string Name { get; set; }
public string DisplayName { get; set; }
public string ControllerId { get; set; }
}
IActionDescriptorCollectionProvider
提供了ActionDescriptor
的缓存集合,每个描述符表示一个操作。打开启动类和内部配置方法并注册MvcControllerDiscovery
依赖项
services.AddSingleton<IMvcControllerDiscovery, MvcControllerDiscovery>();
在Models
目录中创建classRoleViewModel
:
public class RoleViewModel
{
[Required]
[StringLength(256, ErrorMessage = "The {0} must be at least {2} characters long.")]
public string Name { get; set; }
public IEnumerable<MvcControllerInfo> SelectedControllers { get; set; }
}
公共类角色视图模型
{
[必需]
[StringLength(256,ErrorMessage={0}必须至少有{2}个字符长。”)]
公共字符串名称{get;set;}
公共IEnumerable SelectedController{get;set;}
}
并在视图文件夹中添加另一个文件夹,将其命名为Role,然后添加Create.cshtml视图。我使用jQuery.bonsai来显示控制器和操作层次结构
@model RoleViewModel
@{
ViewData["Title"] = "Create Role";
var controllers = (IEnumerable<MvcControllerInfo>)ViewData["Controllers"];
}
@section Header {
<link href="~/lib/jquery-bonsai/jquery.bonsai.css" rel="stylesheet" />
}
<h2>Create Role</h2>
<hr />
<div class="row">
<div class="col-md-6">
<form asp-action="Create" class="form-horizontal">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Name" class="control-label col-md-2"></label>
<div class="col-md-10">
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label">Access List</label>
<div class="col-md-9">
<ol id="tree">
@foreach (var controller in controllers)
{
string name;
{
name = controller.DisplayName ?? controller.Name;
}
<li class="controller" data-value="@controller.Name">
<input type="hidden" class="area" value="@controller.AreaName" />
@name
@if (controller.Actions.Any())
{
<ul>
@foreach (var action in controller.Actions)
{
{
name = action.DisplayName ?? action.Name;
}
<li data-value="@action.Name">@name</li>
}
</ul>
}
</li>
}
</ol>
</div>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script src="~/lib/jquery-qubit/jquery.qubit.js"></script>
<script src="~/lib/jquery-bonsai/jquery.bonsai.js"></script>
<script>
$(function () {
$('#tree').bonsai({
expandAll: false,
checkboxes: true,
createInputs: 'checkbox'
});
$('form').submit(function () {
var i = 0, j = 0;
$('.controller > input[type="checkbox"]:checked, .controller > input[type="checkbox"]:indeterminate').each(function () {
var controller = $(this);
if ($(controller).prop('indeterminate')) {
$(controller).prop("checked", true);
}
var controllerName = 'SelectedControllers[' + i + ']';
$(controller).prop('name', controllerName + '.Name');
var area = $(controller).next().next();
$(area).prop('name', controllerName + '.AreaName');
$('ul > li > input[type="checkbox"]:checked', $(controller).parent()).each(function () {
var action = $(this);
var actionName = controllerName + '.Actions[' + j + '].Name';
$(action).prop('name', actionName);
j++;
});
j = 0;
i++;
});
return true;
});
});
</script>
}
@model RoleViewModel
@{
ViewData[“Title”]=“创建角色”;
变量控制器=(IEnumerable)视图数据[“控制器”];
}
@节头{
}
创建角色
访问列表
@foreach(控制器中的var控制器)
{
字符串名;
{
name=controller.DisplayName??controller.name;
}
@名字
@if(controller.Actions.Any())
{
@foreach(controller.Actions中的var操作)
{
{
name=action.DisplayName??action.name;
}
- @Name
}
}
}
希望这有帮助 看看代替Authorize属性的地方,我想创建一个特权数据表,链接到每个角色,每个操作方法(编辑、创建、删除、详细信息)都表示为bool;使用razor创建如上所述的用户前端,这样当选中复选框时,我可以隐藏或显示不同的元素,然后将复选框isActive保存到dbi找不到IMvcControllerDiscovery命名空间中。我正在使用.NETCore2。1@booota在我的自定义实现中,我没有实现IMvcControllerDiscovery接口。刚刚创建了classI,我尝试了演示,但是当您无法访问控制器时,您如何创建角色?如何在其上创建超级用户?我想不出来。默认用户甚至无法注销删除auth属性。您可以在admin/accesscontroller中创建角色。启动项目时,必须使用.net core 2.0个人授权,才能使其正常工作。否则,将需要进行不必要的工作。使用ind auth时,.NET创建表:AspNetRoles、AspNetUsers。查看服务器资源管理器以查看表/角色@斯沃德尼维斯
public class RoleViewModel
{
[Required]
[StringLength(256, ErrorMessage = "The {0} must be at least {2} characters long.")]
public string Name { get; set; }
public IEnumerable<MvcControllerInfo> SelectedControllers { get; set; }
}
@model RoleViewModel
@{
ViewData["Title"] = "Create Role";
var controllers = (IEnumerable<MvcControllerInfo>)ViewData["Controllers"];
}
@section Header {
<link href="~/lib/jquery-bonsai/jquery.bonsai.css" rel="stylesheet" />
}
<h2>Create Role</h2>
<hr />
<div class="row">
<div class="col-md-6">
<form asp-action="Create" class="form-horizontal">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Name" class="control-label col-md-2"></label>
<div class="col-md-10">
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label">Access List</label>
<div class="col-md-9">
<ol id="tree">
@foreach (var controller in controllers)
{
string name;
{
name = controller.DisplayName ?? controller.Name;
}
<li class="controller" data-value="@controller.Name">
<input type="hidden" class="area" value="@controller.AreaName" />
@name
@if (controller.Actions.Any())
{
<ul>
@foreach (var action in controller.Actions)
{
{
name = action.DisplayName ?? action.Name;
}
<li data-value="@action.Name">@name</li>
}
</ul>
}
</li>
}
</ol>
</div>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script src="~/lib/jquery-qubit/jquery.qubit.js"></script>
<script src="~/lib/jquery-bonsai/jquery.bonsai.js"></script>
<script>
$(function () {
$('#tree').bonsai({
expandAll: false,
checkboxes: true,
createInputs: 'checkbox'
});
$('form').submit(function () {
var i = 0, j = 0;
$('.controller > input[type="checkbox"]:checked, .controller > input[type="checkbox"]:indeterminate').each(function () {
var controller = $(this);
if ($(controller).prop('indeterminate')) {
$(controller).prop("checked", true);
}
var controllerName = 'SelectedControllers[' + i + ']';
$(controller).prop('name', controllerName + '.Name');
var area = $(controller).next().next();
$(area).prop('name', controllerName + '.AreaName');
$('ul > li > input[type="checkbox"]:checked', $(controller).parent()).each(function () {
var action = $(this);
var actionName = controllerName + '.Actions[' + j + '].Name';
$(action).prop('name', actionName);
j++;
});
j = 0;
i++;
});
return true;
});
});
</script>
}