DotNetCore API中基于属性的授权

时间:2018-11-30 04:56:23

标签: c# asp.net-core asp.net-core-2.0

我正在将.NET API代码转换为.NET Core API。在较旧的系统中,有一些具有属性授权的API。据我了解,.NET Core没有属性授权。那么,我该怎么做呢?

我还将在下面的旧系统中提供该属性的示例:

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

我一直在阅读有关policy-based授权的信息,以期完成旧系统的工作。基本上,我想将允许的权限列表传递给API控制器操作。每个呼叫都会针对该列表进行评估,以查看用户是否具有这些权限。

1 个答案:

答案 0 :(得分:2)

要与旧系统兼容,您可以创建一个简单的授权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;
        });
    });
});

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