gpt4 book ai didi

c# - 如何使用 Asp.Net Core 实现基于权限的访问控制

转载 作者:IT王子 更新时间:2023-10-29 04:02:29 26 4
gpt4 key购买 nike

我正在尝试使用 aspnet core 实现基于权限的访问控制。为了动态管理用户角色和权限(create_product、delete_product 等),它们存储在数据库中。数据模型类似于 http://i.stack.imgur.com/CHMPE.png

在 aspnet core(在 MVC 5 中)之前,我使用自定义 AuthorizeAttribute 来处理这个问题,如下所示:

public class CustomAuthorizeAttribute : AuthorizeAttribute
{
private readonly string _permissionName { get; set; }
[Inject]
public IAccessControlService _accessControlService { get; set; }

public CustomAuthorizeAttribute(string permissionName = "")
{
_permissionName = permissionName;
}

public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
var user = _accessControlService.GetUser();
if (PermissionName != "" && !user.HasPermission(_permissionName))
{
// set error result
filterContext.HttpContext.Response.StatusCode = 403;
return;
}
filterContext.HttpContext.Items["CUSTOM_USER"] = user;
}
}

然后我在下面的操作方法中使用它:

[HttpGet]
[CustomAuthorize(PermissionEnum.PERSON_LIST)]
public ActionResult Index(PersonListQuery query){ }

此外,我在 View 中使用 HttpContext.Items["CUSTOM_USER"] 来显示或隐藏 html 部分:

@if (CurrentUser.HasPermission("<Permission Name>"))
{

}

当我决定切换aspnet core时,我所有的计划都失败了。因为 AuthorizeAttribute 中没有虚拟的 OnAuthorization 方法。我尝试了一些方法来解决问题。这些如下:

  • 使用新的基于策略的授权(我认为它不适合我的场景)

  • 使用自定义 AuthorizeAttributeAuthorizationFilter(我读过这个发布https://stackoverflow.com/a/35863514/5426333但我无法正确更改它)

  • 使用自定义中间件(如何获取当前的AuthorizeAttribute行动?)

  • 使用 ActionFilter(出于安全目的是否正确?)

我无法决定哪种方式最适合我的场景以及如何实现它。

第一个问题:MVC5 的实现是不好的做法吗?

第二个问题:您对实现aspnet core有什么建议吗?

最佳答案

根据评论,这里有一个关于如何使用基于策略的授权的例子:

public class PermissionRequirement : IAuthorizationRequirement
{
public PermissionRequirement(PermissionEnum permission)
{
Permission = permission;
}

public PermissionEnum Permission { get; }
}

public class PermissionHandler : AuthorizationHandler<PermissionRequirement>
{
private readonly IUserPermissionsRepository permissionRepository;

public PermissionHandler(IUserPermissionsRepository permissionRepository)
{
if(permissionRepository == null)
throw new ArgumentNullException(nameof(permissionRepository));

this.permissionRepository = permissionRepository;
}

protected override void Handle(AuthorizationContext context, PermissionRequirement requirement)
{
if(context.User == null)
{
// no user authorizedd. Alternatively call context.Fail() to ensure a failure
// as another handler for this requirement may succeed
return null;
}

bool hasPermission = permissionRepository.CheckPermissionForUser(context.User, requirement.Permission);
if (hasPermission)
{
context.Succeed(requirement);
}
}
}

并将其注册到您的Startup 类中:

services.AddAuthorization(options =>
{
UserDbContext context = ...;
foreach(var permission in context.Permissions)
{
// assuming .Permission is enum
options.AddPolicy(permission.Permission.ToString(),
policy => policy.Requirements.Add(new PermissionRequirement(permission.Permission)));
}
});

// Register it as scope, because it uses Repository that probably uses dbcontext
services.AddScope<IAuthorizationHandler, PermissionHandler>();

最后在 Controller 中

[HttpGet]
[Authorize(Policy = PermissionEnum.PERSON_LIST.ToString())]
public ActionResult Index(PersonListQuery query)
{
...
}

这个解决方案的优点是你也可以有多个处理程序来满足一个要求,即如果第一个处理程序成功,第二个处理程序可以确定它失败并且你可以将它与 resource based authorization 一起使用。几乎不需要额外的努力。

基于策略的方法是 ASP.NET Core 团队的首选方法。

来自 blowdart :

We don't want you writing custom authorize attributes. If you need to do that we've done something wrong. Instead you should be writing authorization requirements.

关于c# - 如何使用 Asp.Net Core 实现基于权限的访问控制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36445780/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com