禁止用户执行 WebApi 操作

Forbid users from executing WebApi actions

我有以下从后端数据库中删除订单的 WebApi 操作,仅适用于 AdminOrder 角色的用户。但是,如果用户也在 Readonly 角色中,则操作 return 是一个 HTTP 403 Forbidden 响应。

[Authorize(Roles = "Admin,Order")]
public async Task<IHttpActionResult> Delete(int orderid) {
    if(User.IsInRole("Readonly")) { return Forbidden(); }

    var order = await _repository.Get(orderid);
    if(order != null) {
        await _repository.Delete(orderid);

        return NoContent();
    }
    else {
        return NotFound();
    }
}

我想知道的是,如果用户处于特定角色,是否可以阻止执行操作,这样我就不必在所有可更新数据库操作的开头放置 if(User.IsInRole("Readonly")) { return Forbidden(); }方法,例如

[Authorize(Roles = "Admin,Order")]
[NotAuthorized(Roles = "Readonly")]
public async Task<IHttpActionResult> Delete(int orderid) {

    var order = await _repository.Get(orderid);
    if(order != null) {
        await _repository.Delete(orderid);

        return NoContent();
    }
    else {
        return NotFound();
    }
}

如果用户处于 Readonly 角色,NotAuthorized 操作过滤器将 return 一个 HTTP 403 Forbidden 响应。

这可能吗?

这是实现 [Authorize()] 属性反转的代码,如果用户是一个或多个角色的成员,则禁止他们执行 MVC WebApi 操作。

using System;
using System.Net;
using System.Net.Http;
using System.Security.Principal;
using System.Web.Http;
using System.Web.Http.Controllers;

namespace MyAPI {

    [AttributeUsage(AttributeTargets.Method,AllowMultiple = false)]
    public class NotAuthorizedAttribute : AuthorizeAttribute {

        public override void OnAuthorization(HttpActionContext actionContext) {
            IPrincipal user = actionContext.RequestContext.Principal;
            if(!user.Identity.IsAuthenticated) {
                actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
            }
            else {
                bool userInRole = false;
                foreach(var role in Roles.Split(',')) {
                    if(user.IsInRole(role)) {
                        userInRole = true;
                        break;
                    }
                }
                if(userInRole) {
                    actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden);
                }
            }
        }
    }
}

要使用此过滤器属性,只需装饰您不希望用户执行的任何操作(如果用户是受限角色的成员),例如如果用户是只读角色的一部分,则不允许他们更新数据库:

[Authorize(Roles = "Admin,Order")]
[NotAuthorized(Roles = "Readonly")]
public async Task<IHttpActionResult> Delete(int orderid) {
    var order = await _repository.Get(orderid);
    if(order != null) {
        await _repository.Delete(orderid);

        return NoContent();
    }
    else {
        return NotFound();
    }
}