ID 역할 기반 인증을 구현했지만 각 컨트롤러 / 작업으로 수동으로 이동해야하며 개별적으로 [Authorize(Roles = "")]
매우 낮은 확장 성을 지정해야합니다.
"슈퍼 관리자"가 컨트롤러 / 작업에 대한 액세스 권한이있는 역할을 구성 할 수있는 동적 역할 기반 권한 부여를 사용하여 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; }
}
Services
폴더에 다른 클래스 MvcControllerDiscovery
를 추가하여 모든 컨트롤러와 작업을 찾습니다.
public class MvcControllerDiscovery : IMvcControllerDiscovery
{
private List<MvcControllerInfo> _mvcControllers;
private readonly IActionDescriptorCollectionProvider _actionDescriptorCollectionProvider;
public MvcControllerDiscovery(IActionDescriptorCollectionProvider actionDescriptorCollectionProvider)
{
_actionDescriptorCollectionProvider = actionDescriptorCollectionProvider;
}
public IEnumerable<MvcControllerInfo> GetControllers()
{
if (_mvcControllers != null)
return _mvcControllers;
_mvcControllers = new List<MvcControllerInfo>();
var items = _actionDescriptorCollectionProvider
.ActionDescriptors.Items
.Where(descriptor => descriptor.GetType() == typeof(ControllerActionDescriptor))
.Select(descriptor => (ControllerActionDescriptor)descriptor)
.GroupBy(descriptor => descriptor.ControllerTypeInfo.FullName)
.ToList();
foreach (var actionDescriptors in items)
{
if (!actionDescriptors.Any())
continue;
var actionDescriptor = actionDescriptors.First();
var controllerTypeInfo = actionDescriptor.ControllerTypeInfo;
var currentController = new MvcControllerInfo
{
AreaName = controllerTypeInfo.GetCustomAttribute<AreaAttribute>()?.RouteValue,
DisplayName = controllerTypeInfo.GetCustomAttribute<DisplayNameAttribute>()?.DisplayName,
Name = actionDescriptor.ControllerName,
};
var actions = new List<MvcActionInfo>();
foreach (var descriptor in actionDescriptors.GroupBy(a => a.ActionName).Select(g => g.First()))
{
var methodInfo = descriptor.MethodInfo;
actions.Add(new MvcActionInfo
{
ControllerId = currentController.Id,
Name = descriptor.ActionName,
DisplayName = methodInfo.GetCustomAttribute<DisplayNameAttribute>()?.DisplayName,
});
}
currentController.Actions = actions;
_mvcControllers.Add(currentController);
}
return _mvcControllers;
}
}
IActionDescriptorCollectionProvider
는 각 설명자가 작업을 나타내는 ActionDescriptor
의 캐시 된 컬렉션을 제공합니다. Startup 클래스를 열고 Configure 메서드 내에서 MvcControllerDiscovery
종속성을 등록합니다.
services.AddSingleton<IMvcControllerDiscovery, MvcControllerDiscovery>();
역할 컨트롤러를 추가하여 역할을 관리하십시오. Controller
폴더에서 RoleController
를 Create
한 다음 Create
액션을 추가 Create
:
public class RoleController : Controller
{
private readonly IMvcControllerDiscovery _mvcControllerDiscovery;
public RoleController(IMvcControllerDiscovery mvcControllerDiscovery)
{
_mvcControllerDiscovery = mvcControllerDiscovery;
}
// GET: Role/Create
public ActionResult Create()
{
ViewData["Controllers"] = _mvcControllerDiscovery.GetControllers();
return View();
}
}
Models
클래스에 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; }
}
그리고보기 폴더에서 다른 폴더를 추가하고 역할 이름을 지정한 다음 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>
}
이렇게하면 프런트 엔드의 모든 컨트롤러에있는 각 작업을 표시하여 어느 역할에 대한 권한 액세스를 사용자 지정할 수 있습니다.
신원 사용자로부터 상속하는 클래스가없는 경우 아래 링크의 나머지 단계를 따라 특정 사용자에게 역할을 설정하는 방법을 보여줄 수 있습니다. 행운을 빕니다!
https://github.com/mo-esmp/DynamicRoleBasedAuthorizationNETCore/blob/master/README.md
희망이 도움이됩니다.