【问题标题】:C# MVC Controllers returning Access DeniedC# MVC 控制器返回拒绝访问
【发布时间】:2020-10-20 07:52:31
【问题描述】:

我正在使用 .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"));
});

【问题讨论】:

  • 您好,您可以展示一下 AuthorizationHandler 代码吗?
  • 我……好像没有。在谷歌搜索 AuthorizationHandler 后阅读this page。 (感谢@MichelleWang)已添加IAuthorizationServiceIAuthorizationHandler,但不确定将AuthorizeAsync 作为任务而不是课程放在哪里
  • RequireRole() 采用字符串数组或列表,而不是逗号分隔的值。这可能是你的问题吗?
  • @bugnuker 可能。很确定这是基于 MS 网站上的示例。
  • @bugnuker 我想我在指定 Authorization 属性(它是 csv)和指定角色(不是)之间混淆了。回到办公桌测试时会更新

标签: c# asp.net-mvc asp.net-core roles


【解决方案1】:

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

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

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

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

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

希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-09
    相关资源
    最近更新 更多