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

C# 用户或管理员的ASP.Net核心WebAPI授权策略,c#,asp.net-core,jwt,C#,Asp.net Core,Jwt,我有一个控制器,可以返回有关用户的数据。我想设置授权,以便管理员可以访问此控制器并为任何用户检索数据,而非管理员用户可以访问控制器并为自己检索数据 我已经排除了使用[Authorize(Roles=“Admin”)]的可能性,因为这意味着用户无法获取自己的数据。因此,我在控制器操作中插入了以下逻辑: var userId = _httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.Name).Value; var roles = _h

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

我已经排除了使用
[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.NETCore而不是MVC

我的问题是,有没有一种方法可以通过授权策略实现这一点?添加RequireRole检查非常简单,在中以及无数的博客中都有介绍,但我找不到或想不出一种方法来使用策略检查用户试图访问的数据是否是他们自己的


我相信这不是一个不寻常的要求,有没有办法做到这一点,或者我目前正在做的事情可以吗?我唯一能想到的另一种方法是有两个独立的端点,但这两个选项似乎都不美观。

该策略用于授权,但管理员或普通用户都可以访问控制器,它们都是经过授权的

这是您确定应该返回哪些数据的自定义逻辑,与授权无关。如果您坚持使用策略,您可以将逻辑放入处理程序,但当逻辑位于控制器中时,这不会改变:

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;
    }
}

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

用户返回他/她的数据,管理员返回所有用户的信息。它们是两种不同的功能,您可以使用两种不同的功能。若管理员只想返回他自己的信息怎么办?用户返回他们的数据,用户是管理员,只想返回他们自己的数据。好的,他们点击端点,给我用户X的数据。用户是在请求用户X的信息吗?或者他们是管理员?如果其中一个为真,则返回数据。同样的逻辑适用,问题仍然存在——这可以通过授权策略实现吗?替代方案(可能是您的建议)是用[Authorize(Roles=“Admin”)]注释一个端点,为任何用户提供数据,另一个端点只需要登录用户,它不允许您指定要为哪个用户获取数据,而是在声明中查找该用户并返回该用户的数据。这就是你的建议吗?根据我的问题,这似乎不雅,似乎违反了干燥原则。感谢您花时间回答。两条评论—“该策略用于授权,但是管理员或普通用户都可以访问控制器,他们都是授权的”。我明白你在这里所说的,当与“在我的选项中,在你的web api中设置两个端点/函数,一个用于管理员,一个用于用户是干净的方式”相结合时,我理解你关于授权的建议应该是访问端点,而不是访问数据。这回答了我的问题,也是我在问题中提出的选择之一。我的另一个意见是:“此外,您的客户端应用程序有责任确定当前用户是否希望返回自己的数据或所有用户的数据。将请求发送到web api并让api通过逻辑确定,这似乎不太正确。Webapi应该包括干净的函数/端点,以映射来自客户端的每个请求。“请放心,客户端应用程序可以做到这一点。然而,我认为将安全性完全放在客户机中不是一个好的设计。提供数据访问权限的API也应该确定请求是否得到了适当的授权。因此,您可以尝试在web API端设置两个函数,并使用策略授权使admin one应该使用admin角色进行访问。
var message = HttpContext.Items["message"];