DynamicAuthorization.Mvc.Core 1.2.2
dotnet add package DynamicAuthorization.Mvc.Core --version 1.2.2
NuGet\Install-Package DynamicAuthorization.Mvc.Core -Version 1.2.2
<PackageReference Include="DynamicAuthorization.Mvc.Core" Version="1.2.2" />
paket add DynamicAuthorization.Mvc.Core --version 1.2.2
#r "nuget: DynamicAuthorization.Mvc.Core, 1.2.2"
// Install DynamicAuthorization.Mvc.Core as a Cake Addin #addin nuget:?package=DynamicAuthorization.Mvc.Core&version=1.2.2 // Install DynamicAuthorization.Mvc.Core as a Cake Tool #tool nuget:?package=DynamicAuthorization.Mvc.Core&version=1.2.2
ASP.NET Core MVC 2.1, 3.1, 5.0 和 6.0 的动态基于角色的授权 
您已经知道 ASP.NET Core 中的角色授权是如何工作的。
[Authorize(Roles = "Administrator")]
public class AdministrationController : Controller
{
}
但是,如果您不想在 Authorize
属性上硬编码角色或创建角色然后在源代码中指定控制器的访问而不修改源代码该怎么办?
DynamicAuthorization 帮助您以最小的努力在不硬编码角色的情况下授权用户。《DynamicAuthorization》建立在 ASP.NET Core Identity 的基础上,并使用身份机制来管理角色和授权用户。
安装 DynamicAuthorization.Mvc.Core NuGet 包
Install-Package DynamicAuthorization.Mvc.Core
或
dotnet add package DynamicAuthorization.Mvc.Core
然后,在 Startup.ConfigureServices
方法中将 AddDynamicAuthorization()
添加到 IServiceCollection
public void ConfigureServices(IServiceCollection services)
{
...
services
.AddIdentity<IdentityUser, IdentityRole>(options => options.SignIn.RequireConfirmedAccount = false)
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services
.AddDynamicAuthorization<ApplicationDbContext>(options => options.DefaultAdminUser = "UserName")
您可以通过 DefaultAdminUser
配置设置默认管理员用户名,以便无创建默认管理员角色及其权限即可访问任何地方。
然后安装 JSON 或 SQLSever 存储以保存角色访问。
要安装 DynamicAuthorization.Mvc.JsonStore NuGet 包
Install-Package DynamicAuthorization.Mvc.JsonStore
或
dotnet add package DynamicAuthorization.Mvc.JsonStore
public void ConfigureServices(IServiceCollection services)
{
services
.AddDynamicAuthorization<ApplicationDbContext>(options => options.DefaultAdminUser = "UserName")
.AddJsonStore(options => options.FilePath = "FilePath");
角色访问将保存在一个JSON文件中,您可以指定文件路径的FilePath
配置。
或者安装SQLServer存储DynamicAuthorization.Mvc.MsSqlServerStore NuGet包
Install-Package DynamicAuthorization.Mvc.MsSqlServerStore
或
dotnet add package DynamicAuthorization.Mvc.MsSqlServerStore
public void ConfigureServices(IServiceCollection services)
{
services
.AddDynamicAuthorization<ApplicationDbContext>(options => options.DefaultAdminUser = "UserName")
.AddSqlServerStore(options => options.ConnectionString = "ConnectionString");
您可以使用DisplayName
属性来装饰控制器和动作,以向用户显示更有意义的名称而不是控制器和动作名称。
[DisplayName("Access Management")]
public class AccessController : Controller
{
// GET: Access
[DisplayName("Access List")]
public async Task<ActionResult> Index()
}
如果不希望自行实现,您也可以使用用于管理角色和分配角色给用户的默认UI。
安装DynamicAuthorization.Mvc.Ui NuGet包
Install-Package DynamicAuthorization.Mvc.Ui
然后将AddUi
添加到DynamicAuthorization注册中
services
.AddDynamicAuthorization<ApplicationDbContext>(options => options.DefaultAdminUser = "UserName")
.AddJsonStore(options => options.FilePath = "FilePath")
.AddUi();
使用http://<your-app>/role
URL来管理角色和分配访问权限给角色。
使用http://<your-app>/userrole
URL来为用户分配角色。
您还可以使用自定义的TageHelper
来检查用户是否有权查看内容。创建一个继承自SecureContentTagHelper
的自定义标签助手
[HtmlTargetElement("secure-content")]
public class MySecureContentTagHelper : SecureContentTagHelper<ApplicationDbContext>
{
public MySecureContentTagHelper(
ApplicationDbContext dbContext,
DynamicAuthorizationOptions authorizationOptions,
IRoleAccessStore roleAccessStore
)
: base(dbContext, authorizationOptions, roleAccessStore)
{
}
}
在每个视图中,在secure-content
标签内部包裹内容或锚点标签
<ul class="nav navbar-nav">
<li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li>
<li><a asp-area="" asp-controller="Home" asp-action="About">About</a></li>
<li><a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a></li>
<secure-content asp-area="" asp-controller="Role" asp-action="Index">
<li><a asp-area="" asp-controller="Role" asp-action="Index">Role</a></li>
</secure-content>
<secure-content asp-area="" asp-controller="Access" asp-action="Index">
<li><a asp-area="" asp-controller="Access" asp-action="Index">Access</a></li>
</secure-content>
</ul>
别忘了将您的标签助手命名空间添加到_ViewImports.cshtml
@using SampleMvcWebApp
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, SampleMvcWebApp
如果您扩展了IdentityUser
或更改了用户和角色键,也应该传递用户和角色类型。例如
public class ApplicationDbContext : IdentityDbContext<ApplicationUser> { ... }
public class MySecureContentTagHelper : SecureContentTagHelper<ApplicationDbContext, ApplicationUser> { ... }
或
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, int> { ... }
public class MySecureContentTagHelper : SecureContentTagHelper<ApplicationDbContext, ApplicationUser, ApplicationRole, int> { ... }
如果您不希望使用默认的UI,按照以下步骤发现控制器和动作,然后为角色授权,最后将角色分配给用户。下一步是发现控制器和动作。`IMvcControllerDiscovery`返回所有带有[Authorize]
属性的控制器和动作。`IMvcControllerDiscovery.GetControllers()`方法返回一个包含MvcControllerInfo
的列表
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; }
}
下一步是创建一个角色以向其分配访问权限。使用`RoleManager<>来创建角色,使用`IRoleAccessStore来存储角色访问。
var role = new IdentityRole { Name = "RoleName" };
var result = await _roleManager.CreateAsync(role);
var controllers = _mvcControllerDiscovery.GetControllers();
var roleAccess = new RoleAccess
{
Controllers = controllers.First(),
RoleId = role.Id
};
await _roleAccessStore.AddRoleAccessAsync(roleAccess);
最后一步是将创建的角色分配给用户
var user = await _userManager.FindByIdAsync("someId");
await _userManager.AddToRolesAsync(user, new [] { "RoleName" });
现在用户只能访问其角色能够访问的控制器和动作。
以下是一个创建角色并向其分配访问权限的示例。
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; }
}
[DisplayName("Role Management")]
public class RoleController : Controller
{
private readonly IMvcControllerDiscovery _mvcControllerDiscovery;
private readonly IRoleAccessStore _roleAccessStore;
private readonly RoleManager<IdentityRole> _roleManager;
public RoleController(
IMvcControllerDiscovery mvcControllerDiscovery,
IRoleAccessStore roleAccessStore,
RoleManager<IdentityRole> roleManager
)
{
_mvcControllerDiscovery = mvcControllerDiscovery;
_roleManager = roleManager;
_roleAccessStore = roleAccessStore;
}
// GET: Role/Create
[DisplayName("Create Role")]
public ActionResult Create()
{
var controllers = _mvcControllerDiscovery.GetControllers();
ViewData["Controllers"] = controllers;
return View();
}
// POST: Role/Create
[HttpPost, ValidateAntiForgeryToken]
public async Task<ActionResult> Create(RoleViewModel viewModel)
{
if (!ModelState.IsValid)
{
ViewData["Controllers"] = _mvcControllerDiscovery.GetControllers();
return View(viewModel);
}
var role = new IdentityRole { Name = viewModel.Name };
var result = await _roleManager.CreateAsync(role);
if (!result.Succeeded)
{
foreach (var error in result.Errors)
ModelState.AddModelError("", error.Description);
ViewData["Controllers"] = _mvcControllerDiscovery.GetControllers();
return View(viewModel);
}
if (viewModel.SelectedControllers != null && viewModel.SelectedControllers.Any())
{
foreach (var controller in viewModel.SelectedControllers)
foreach (var action in controller.Actions)
action.ControllerId = controller.Id;
var roleAccess = new RoleAccess
{
Controllers = viewModel.SelectedControllers.ToList(),
RoleId = role.Id
};
await _roleAccessStore.AddRoleAccessAsync(roleAccess);
}
return RedirectToAction(nameof(Index));
}
}
查看示例以查看完整的实现。
要自己一步一步地实现DynamicAuthorization,请查看手动分支。
产品 | 版本 兼容和额外的计算目标框架版本。 |
---|---|
.NET | net5.0 兼容。 net5.0-windows 已计算。 net6.0 兼容。 net6.0-android 已计算。 net6.0-ios 已计算。 net6.0-maccatalyst 已计算。 net6.0-macos 已计算。 net6.0-tvos 已计算。 net6.0-windows 已计算。 net7.0 兼容。 net7.0-android 已计算。 net7.0-ios 已计算。 net7.0-maccatalyst 已计算。 net7.0-macos 已计算。 net7.0-tvos 已计算。 net7.0-windows 已计算。 net8.0 已计算。 net8.0-android 已计算。 net8.0-browser 已计算。 net8.0-ios 已计算。 net8.0-maccatalyst 已计算。 net8.0-macos 已计算。 net8.0-tvos 已计算。 net8.0-windows 已计算。 |
.NET Core | netcoreapp3.1 兼容。 |
-
.NETCoreApp 3.1
-
net5.0
-
net6.0
-
net7.0
NuGet 包 (3)
显示依赖 DynamicAuthorization.Mvc.Core 的前三项 NuGet 包
包 | 下载 |
---|---|
DynamicAuthorization.Mvc.MsSqlServerStore
DynamicAuthorization 的 SQL Server 存储库 |
|
DynamicAuthorization.Mvc.Ui
为 DynamicAuthorization 创建角色和角色访问权限的简单 web UI |
|
DynamicAuthorization.Mvc.JsonStore
DynamicAuthorization 的 JSON 存储 |
GitHub 仓库
此包不受任何流行的 GitHub 仓库的使用。