【问题标题】:ASP.NET Core 3.1 - Access deniedASP.NET Core 3.1 - 访问被拒绝
【发布时间】:2020-08-09 07:48:05
【问题描述】:

我是 ASP.NET Core 3.1 Razor Pages 的新手,我有一个问题。 希望你能帮我更多 :)。

我想要的是一个具有 Windows AD 安全性的应用程序。 我想做什么的描述:

  • 客户需要使用他/她的 AD 帐户登录。
  • 如果输入了有效的 AD 帐户/密码组合,用户将获得授权。
  • 用户有权查看/调整特定页面,如果在特定组中,假设是否在运行应用程序的服务器的管理员组中。

我遇到的问题如下。 在 LaunchSettings.json 我放置了这段代码:

    "windowsAuthentication": true,
    "anonymousAuthentication": false,
    "iisExpress": {
      "applicationUrl": "http://localhost:65385",
      "sslPort": 44356
    }
  } 

然后在 Startup.cs 我添加了 AddAuthentication。

    public void ConfigureServices(IServiceCollection services)
    {
      services.AddAuthentication(IISDefaults.AuthenticationScheme);
      services.AddRazorPages();
    }

在配置部分:

      app.UseAuthentication();
      app.UseAuthorization();

最后,我在我的 Pages 文件夹中创建了一个名为 Admin 的单独文件夹。 我想将此文件夹限制为仅管理员组。 所以我将 Authorize 添加到 Index1Model。

  [Authorize(Roles = "Administrators")]
  public class Index1Model : PageModel
    {
        public void OnGet()
        {
        }
    }

使用 IIS Express 在本地启动此代码并单击受保护的页面,我确实收到以下错误:

Access denied

我认为这可能与模仿有关。但是当我在 IIS 中启用它时,我就无法再打开应用程序了。显示在我的程序右上角的用户属于管理员组,因此应该允许查看该页面。 我在看什么?感谢您帮助我!

【问题讨论】:

  • 您是否在 IIS 中启用了 Windows 身份验证?
  • @YankTHEcode,是的,基本身份验证和 Windows 身份验证都已启用。

标签: c# asp.net asp.net-core razor-pages


【解决方案1】:

您是否在 IIS 中启用了 Windows 身份验证?如果不尝试,则允许匿名身份验证,并在页面上的某个位置显示用户及其角色,以便您可以看到在 IIS 上流经的身份。 您可能需要更改运行应用程序池的标识,但我确信这与您的 IIS 配置有关。

【讨论】:

  • 是的,我在 IIS 中启用了基本身份验证和 Windows 身份验证。使用此代码检查所有组:var identity = User.Identity as WindowsIdentity; var groupNames = from id in identity.Groups select id.Translate(typeof(NTAccount)).Value; Groups = groupNames.ToList();
  • 我在本地看到的,当我使用 IISExpress 启动我的项目时,我测试的用户不在 BUILTIN\Administrators 中。虽然此用户实际上在该组中。如果我在添加为应用程序时使用 IIS 进行测试,则同样适用。有什么想法吗?
【解决方案2】:

据我所知,Windows 身份验证只会检查用户是否经过身份验证。它不会在 MVC 应用程序中提供任何基于角色的控制。

所以你的 Authorize 属性将毫无用处。

要实现基于 AD 角色的授权,我建议您可以考虑使用基于策略的授权来验证只有来自 Active Directory 组的用户才能访问该页面。详情可以参考article

您可以创建自定义策略授权处理程序来检查用户的所有 ADGroups 并检查它们是否包含您想要的组名。

更多细节,您可以参考以下步骤:

1.创建CheckADGroupRequirement(接受参数)

public class CheckADGroupRequirement : IAuthorizationRequirement
    {
        public string GroupName { get; private set; }

        public CheckADGroupRequirement(string groupName)
        {
            GroupName = groupName;
        }
    }

2.创建处理程序

public class CheckADGroupHandler : AuthorizationHandler<CheckADGroupRequirement>
    {
        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
                                                       CheckADGroupRequirement requirement)
        {
            //var isAuthorized = context.User.IsInRole(requirement.GroupName);

            var groups = new List<string>();//save all your groups' name
            var wi = (WindowsIdentity)context.User.Identity;
            if (wi.Groups != null)
            {
                foreach (var group in wi.Groups)
                {
                    try
                    {
                        groups.Add(group.Translate(typeof(NTAccount)).ToString());
                    }
                    catch (Exception e)
                    {
                        // ignored
                    }
                }
               if(groups.Contains(requirement.GroupName))//do the check
                {
                    context.Succeed(requirement);
                }
            }

            return Task.CompletedTask;
        }
    }

3.在ConfigureServices中注册Handler

services.AddAuthorization(options =>
{
    options.AddPolicy("ADRoleOnly", policy =>
        policy.Requirements.Add(new CheckADGroupRequirement("DOMAIN\\Domain Admin")));
});

services.AddSingleton<IAuthorizationHandler, CheckADGroupHandler>();

4.控制器

[Authorize(Policy = "ADRoleOnly")]
 public class ADController : Controller

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-10-02
    • 2017-12-12
    • 1970-01-01
    • 1970-01-01
    • 2013-12-15
    • 1970-01-01
    • 2018-08-21
    • 1970-01-01
    相关资源
    最近更新 更多