【问题标题】:Role based authorization in ASP.Core 3: how to grant access everywhere to certain role?ASP.Core 3 中基于角色的授权:如何授予对特定角色的任何地方的访问权限?
【发布时间】:2020-04-09 22:44:12
【问题描述】:

我正在编写一个 ABAC 系统,我将在其中根据某些角色/属性/等来决定用户是否可以访问某些数据。但是,有一种特殊的用户(例如超级管理员)应该能够随时随地访问所有内容。我不想遍历所有策略、控制器、操作和方法,并添加对这个特定角色的检查。有没有办法以更集中的方式做到这一点? (例如:在startup)。

如果无法将其添加到全局位置,我正在考虑至少在控制器级别全局添加它:我正在查看 here 并且我看到装饰器 [Authorize(Roles = "Administrator")] 允许您限制访问仅针对管理员用户的某个方法/类。但是,我想要一种“相反的”。我的意思是像 AuthorizeAlways 这样的行为:

[AuthorizeAlways(Roles = "SuperAdministrator")]
public class ControlPanelController : Controller
{
    [Authorize(Roles = "SetterUser")]
    public ActionResult SetTime()
    {
    }

    [Authorize(Roles = "PowerUser")]
    [MinimumAgeAuthorize(50)]
    public ActionResult ShutDown()
    {
    }
}

在这种情况下,我希望SuperAdministrator(即使他们已经 49 岁)可以访问任何地方。 SetterUser 只能访问 SetTime,并且只有 50 岁以上的 PowerUser 才能访问 ShutDown

我不知道这是否有意义。可能吗?我在哪里可以做到?谢谢!

【问题讨论】:

    标签: c# asp.net-core .net-core .net-core-3.0 abac


    【解决方案1】:

    这篇博文为如何实现自定义授权提供了一个很好的教程: https://seanspaniel.wordpress.com/2019/12/13/custom-authorization-in-asp-net-core-3/

    从该教程中,您可以在 CustomAuthorizationMiddleware 类中检查“超级管理员”角色并授予对每个端点的访问权限。

    public static class CustomAuthorizationMiddleware
    {
        public static async Task Authorize(HttpContext httpContext, Func next)
        {
            var endpointMetaData = httpContext.GetEndpoint().Metadata;
    
            bool hasCustomAuthorizeAttribute = endpointMetaData.Any(x => x is CustomAuthorizeAttribute);
    
            if (!hasCustomAuthorizeAttribute)
            {
                await next.Invoke();
                return;
            }
    
            CustomAuthorizeAttribute customAuthorizeAttribute = endpointMetaData
                    .FirstOrDefault(x => x is CustomAuthorizeAttribute) as CustomAuthorizeAttribute;
    
            // Check if user has allowed role or super administrator role
            bool isAuthorized = customAuthorizeAttribute.AllowedUserRoles
                .Any(allowedRole => httpContext.User.IsInRole(allowedRole)) 
                 || httpContext.User.IsInRole("SuperAdministrator");
    
            if (isAuthorized)
            {
                await next.Invoke();
                return;
            }
    
            httpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
            await httpContext.Response.WriteAsync("unauthorized");
        }
    }
    

    【讨论】:

    • 注册中间件时,请确保在身份验证后添加它 - 这样用户就会通过身份验证,并且他们的信息会在端点授权之前添加到 HttpContext 中。否则 httpContext.User 将没有用户的信息,您将始终得到未经授权的响应。
    • 是的,我有userRouting,然后是useCorsuseAuthentication,然后是useAuthorization。我不明白你的教程为什么不使用useAuthorization,虽然...
    • UseAuthorization 扩展方法是微软提供的内置中间件——如果你想实现自己的授权逻辑,你必须用自定义中间件替换它。这就是本教程的用途。如果您不熟悉中间件和请求管道,您可以在此处阅读文档:docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware/…
    猜你喜欢
    • 2012-02-03
    • 2019-05-16
    • 2021-05-12
    • 2020-05-15
    • 2019-12-08
    • 1970-01-01
    • 2022-01-01
    • 2018-10-11
    相关资源
    最近更新 更多