禁止用户执行 WebApi 操作
Forbid users from executing WebApi actions
我有以下从后端数据库中删除订单的 WebApi 操作,仅适用于 Admin
和 Order
角色的用户。但是,如果用户也在 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();
}
}
我有以下从后端数据库中删除订单的 WebApi 操作,仅适用于 Admin
和 Order
角色的用户。但是,如果用户也在 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();
}
}