DotNetCore 中基于属性的授权 API

Attribute-based authorization in DotNetCore API

我正在将 .NET APIs 代码转换为 .NET Core APIs。有几个API在旧系统中有属性授权。据我了解,.NET Core 没有属性授权。那么,我怎样才能达到同样的效果呢?

我还将在下面给出旧系统的属性示例:

[RequiredPermission("100,101,102")]

我一直在阅读有关 policy-based 授权的文章,希望能够完成旧系统所做的事情。基本上,我想将允许的权限列表传递给 API 控制器操作。每个调用都会根据该列表进行评估,以查看用户是否具有这些权限。

为了与旧系统兼容,您可以创建一个简单的授权 Filter :

public class RequiredPermissionAttribute : Attribute, IAsyncAuthorizationFilter{

    public RequiredPermissionAttribute(string permissions)
    {
        this.Permissions = string.IsNullOrEmpty(permissions) ?
            new List<string>():
            permissions.Split(",").Select(p =>p.Trim()).ToList();
    }

    public IList<string> Permissions {get;set;}

    public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
    {
        var user = context.HttpContext.User;

        var authZService = context.HttpContext.RequestServices.GetRequiredService<IAuthorizationService>();
        var accessable = await authZService.AuthorizeAsync(user,this.Permissions,"Require Permissions Policy");
        if(!accessable.Succeeded){
            context.Result =  new ForbidResult();
        }
    }
}

现在您可以使用授权过滤器拦截请求了:

[RequiredPermission("101,102,103")]
public IActionResult Contact()
{
    ViewData["Message"] = "Your contact page.";

    return View();
}

当然,我们需要先注册保单。 :

services.AddAuthorization( o=> {
    o.AddPolicy("Require Permissions Policy", pb =>{
        pb.RequireAssertion(async context =>{
            var user = context.User;
            var permissions=context.Resource as IList<string>;
            if(permissions == null || permissions.Count()==0 ){ return true; }
            if(user.Claims.Any( c => c.Type=="MyCustomClaimType" && permissions.Any(p => p.Equals(c.Value)) ))
            {
                return true;
            }
            return false;
        });
    });
});

出于测试目的,我只是添加了一个简单的功能来检查策略,您可以根据需要自定义授权过程。