ASP.Net 用户或管理员的核心 WebAPI 授权策略



我有一个返回用户数据的控制器。我想设置授权,以便管理员可以访问此控制器并为任何用户检索数据,非管理员用户可以访问控制器并为自己检索数据。

我已经排除了使用[Authorize (Roles = "Admin")],因为这意味着用户无法获取自己的数据。因此,我将以下逻辑插入到控制器操作中:

var userId = _httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.Name).Value;
var roles = _httpContextAccessor.HttpContext.User.FindAll(ClaimTypes.Role);
var query = roles.Select(r => r.Value).Contains("Admin");
Customer customer =await _context.Customers.FindAsync(id);
if (!(customer.EmailAddress == userId || query))
return Unauthorized();

这大致相当于这个堆栈溢出答案,但针对 ASP.Net 核心而不是MVC。

我的问题是,有没有办法使用授权策略来做到这一点?添加 RequireRole 检查很简单,并且在 MS 文档和无数博客中都有介绍,但我找不到或找到一种方法来使用策略来检查用户尝试访问的数据是否是他们自己的。

我确定这不是一个罕见的要求,有没有办法做到这一点,或者我目前做的正常?我能想到的唯一另一种方法是有两个单独的端点,但这两个选项似乎都不优雅。

该策略是用于授权的,但无论是管理员还是普通用户都可以访问控制器,他们都是被授权的。

那是你确定应该返回哪些数据的自定义逻辑,这与授权无关。如果您坚持使用策略,则可以将逻辑放入处理程序,但是当逻辑在控制器中时,这没有任何变化:

public class CustomerHandler : AuthorizationHandler<CustomerRequirement>
{
IHttpContextAccessor _httpContextAccessor = null;
public CustomerHandler(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
CustomerRequirement requirement)
{
HttpContext httpContext = _httpContextAccessor.HttpContext;
//your logic 
httpContext.Items["message"] = "ownData";
context.Succeed(requirement);
return Task.CompletedTask;
}
}

并读取控制器,以便您可以知道是读取自己的数据还是所有用户的数据:

var message = HttpContext.Items["message"];

在我的选项中,在您的Web api中设置两个端点/函数,一个用于管理员,一个用于用户是干净的方式。此外,这是客户端应用的责任,以确定当前用户是否要返回自己的数据或所有用户的数据。将请求发送到 web api 并让 api 通过逻辑确定似乎不太正确。Webapi 应该包括干净的函数/端点来映射来自客户端的每个请求。

最新更新