我有以下WebApi操作,该操作会删除后端数据库中的订单,仅适用于Admin
和Order
角色的用户。但是,如果用户也处于Readonly
角色,则该操作会返回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();
}
}
如果用户处于NotAuthorized
角色,HTTP 403 Forbidden
操作过滤器将返回Readonly
响应。
这可能吗?
答案 0 :(得分:0)
这是实现[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();
}
}