【发布时间】:2019-09-11 00:53:10
【问题描述】:
我有一个返回用户数据的控制器。我想设置授权,以便管理员可以访问此控制器并为任何用户检索数据,而非管理员用户可以访问控制器并为自己检索数据。
我已排除使用[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();
这大致相当于this Stack Overflow answer,但用于 ASP.Net Core 而不是 MVC。
我的问题是,有没有办法通过授权策略来做到这一点?添加 RequireRole 检查很简单,在 MS Documentation 以及无数博客中都有介绍,但我找不到或想出一种方法来使用策略来检查用户尝试访问的数据是否是他们自己的。
我确定这不是一个不常见的要求,有没有办法做到这一点,或者我目前正在做的事情还可以吗?我能想到的唯一其他方法是有两个单独的端点,但这两种选择似乎都不优雅。
【问题讨论】:
-
用户返回他/她的数据,管理员返回所有用户的信息。它们是两种不同的功能,您可以使用两种不同的功能。如果管理员只想返回他自己的信息怎么办?
-
用户返回他们的数据,用户是管理员并且只想返回他们自己的数据。好的,所以他们到达终点,给我用户 X 的数据。用户是否在请求用户 X 的信息?还是他们是管理员?如果其中一个为真,则返回数据。同样的逻辑适用,问题仍然存在——这可以通过授权策略来完成吗?
-
另一种选择(可能是您所建议的)是让一个端点用 [Authorize(Roles="Admin")] 注释,它为任何用户提供数据,另一个只需要登录在用户中,它不允许您指定要为哪个用户提供数据,而是会在声明中查找用户并返回该用户的数据。这就是你的建议吗?根据我的问题,这似乎不优雅,似乎违反了 DRY 原则。
标签: c# asp.net-core jwt