首页 > 解决方案 > C# MVC 控制器返回拒绝访问

问题描述

我正在使用 .net core 3.1 编写一个 MVC 应用程序。

我在 Startup.cs 中设置了用户策略。有一个整体管理员角色,以及每个区域的用户和管理员角色。角色存在于 AspNetRoles 表中,并已链接到 AspNetUserRoles 中的用户

services.AddAuthorization(options =>
{
    options.AddPolicy("RequireAuthenticatedUserPolicy", policy => policy.RequireAuthenticatedUser());
    options.AddPolicy("RequireAdmin", policy => policy.RequireRole("Admin"));
    options.AddPolicy("RequireUserAnchor", policy => policy.RequireRole("Admin,AnchorUser,AnchorAdmin"));
    options.AddPolicy("RequireUserDashboard", policy => policy.RequireRole("Admin,DashboardUser,DashboardAdmin"));
    options.AddPolicy("RequireUserReportGroups", policy => policy.RequireRole("Admin,ReportGroupsUser,ReportGroupsAdmin"));
    options.AddPolicy("RequireUserMaintenance", policy => policy.RequireRole("Admin,MaintenanceUser,MaintenanceAdmin"));
    options.AddPolicy("RequireUserMaps", policy => policy.RequireRole("Admin,MapsUser,MapsAdmin"));
    options.AddPolicy("RequireAdminAnchor", policy => policy.RequireRole("Admin,AnchorAdmin"));
    options.AddPolicy("RequireAdminDashboard", policy => policy.RequireRole("Admin,DashboardAdmin"));
    options.AddPolicy("RequireAdminReportGroups", policy => policy.RequireRole("Admin,ReportGroupsAdmin"));
    options.AddPolicy("RequireAdminMaintenancen", policy => policy.RequireRole("Admin,MaintenanceAdmin"));
    options.AddPolicy("RequireAdminMaps", policy => policy.RequireRole("Admin,MapsAdmin"));
});

这些区域在其控制器定义上具有属性。例如:GroupsController

[Area("ReportGroups")]
[Authorize(Policy = "RequireUserReportGroups")]
public class GroupsController : Controller
{

用户角色用于修改站点菜单,仅在 _Layout.cshtml 中显示他们有权访问的部分

@if (User.IsInRole("Admin"))
{
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Admin" asp-controller="Admin" asp-action="Index"><i class="fas fa-2x fa-chess-king" title="Admin"></i></a>
    </li>
}
@if (User.Identity.IsAuthenticated)
{
    <li class="nav-item">
        <span style="font-weight:bold; font-size:16px;">ORG<br />@User.Identity.GetOrgCode()</span>
    </li>
}
@if (User.IsInRole("AnchorUser") || User.IsInRole("Admin"))
{
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Anchor" asp-controller="Home" asp-action="Index">
            <i class="fas fa-2x fa-anchor" title="Anchor"></i>
        </a>
    </li>
}

@if (User.IsInRole("DashboardUser") || User.IsInRole("DashboardAdmin") || User.IsInRole("Admin"))
{
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Dashboard" asp-controller="DriverBehaviour" asp-action="Index">
            <i class="fas fa-2x fa-chart-area" title="Dashboard"></i>
        </a>
    </li>
}

主页上的链接正确呈现。例如:https://localhost:44322/Maintenance/Home

单击它们时,它们会重定向到例如:https://localhost:44322/Account/AccessDenied?ReturnUrl=%2FMaintenance除了无法按预期工作之外,还会出现 404 错误。

查询角色成员资格并让它返回 true 将表明我有权限。我在某处错过了一些配置吗?我错误地查询角色?

有一个问题。AdminController 返回正常。它是一个基本的脚手架控制器,只有一个视图,上面写着“这是管理控制器”


编辑 2020-07-01

解决方案是更改RequireRole. 它是字符串列表,而不是逗号分隔的字符串。这也是唯一使用 RequireAdmin 的页面起作用的原因。

services.AddAuthorization(options =>
{
    options.AddPolicy("RequireAuthenticatedUserPolicy", policy => policy.RequireAuthenticatedUser());
    options.AddPolicy("RequireAdmin", policy => policy.RequireRole("Admin"));
    options.AddPolicy("RequireUserAnchor", policy => policy.RequireRole("Admin","AnchorUser","AnchorAdmin"));
    options.AddPolicy("RequireUserDashboard", policy => policy.RequireRole("Admin","DashboardUser","DashboardAdmin"));
    options.AddPolicy("RequireUserReportGroups", policy => policy.RequireRole("Admin","ReportGroupsUser","ReportGroupsAdmin"));
    options.AddPolicy("RequireUserMaintenance", policy => policy.RequireRole("Admin","MaintenanceUser","MaintenanceAdmin"));
    options.AddPolicy("RequireUserMaps", policy => policy.RequireRole("Admin","MapsUser","MapsAdmin"));
    options.AddPolicy("RequireAdminAnchor", policy => policy.RequireRole("Admin","AnchorAdmin"));
    options.AddPolicy("RequireAdminDashboard", policy => policy.RequireRole("Admin","DashboardAdmin"));
    options.AddPolicy("RequireAdminReportGroups", policy => policy.RequireRole("Admin","ReportGroupsAdmin"));
    options.AddPolicy("RequireAdminMaintenancen", policy => policy.RequireRole("Admin","MaintenanceAdmin"));
    options.AddPolicy("RequireAdminMaps", policy => policy.RequireRole("Admin","MapsAdmin"));
});

标签: c#asp.net-mvcasp.net-coreroles

解决方案


在您的示例中,您使用逗号分隔的角色名称值(见下文)

options.AddPolicy("RequireUserAnchor", policy => policy.RequireRole("Admin,AnchorUser,AnchorAdmin"));

“RequireRole”方法采用字符串数组或列表。

您可以尝试将代码更改为:

options.AddPolicy("RequireUserAnchor", policy => policy.RequireRole(new string[] {"Admin","AnchorUser","AnchorAdmin"}));

希望这会有所帮助!


推荐阅读