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
目录中创建class
RoleViewModel

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>
    }