我正在处理一个场景,我用ActionFilterAttribute
检查记录所有权的方式要求我通过操作处理的模型类型以及id参数,如下所示:
[CheckOwnership(objectId = "clientid", Model = typeof(Client))]
然后检查用户的companyId是否与记录的companyId匹配,如下所示:
public class CheckOwnership : ActionFilterAttribute
{
public string objectId { get; set; }
public object Model { get; set; }
private MyDatabaseContext db = new MyDatabaseContext();
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.ActionParameters.ContainsKey(objectId))
{
var id = filterContext.ActionParameters[objectId] as Int32?;
var model = Model;
if (model.GetType() == typeof(Client))
{
var companyId = SharedLogic.GetCurrentCompanyId();
var clientCompanyId = db.Clients.Find(id).CompanyId;
if (companyId != clientCompanyId)
{
// deauthorize user
}
}
}
}
}
问题在于"取消授权"用户如果不以[Authorize]
属性的方式拥有该记录,则将用户返回到登录页面。
我知道如何执行此操作的唯一方法是构建自定义AuthorizeAttribute
,但这不允许我访问在用户发出请求时传递给方法的id参数。通过使用ActionFilterAttribute
,我可以访问ActionExecutingContext,我可以使用它来检索参数等。
有没有办法取消授权用户并将其返回到登录页面而不使用authorize属性?
答案 0 :(得分:2)
您应该使用AuthorizeAttribute
而不是ActionFilterAttribute
。
您无法访问模型的原因是授权在模型绑定器之前运行,因此在执行attiribute OnAuthorization
方法时模型不存在。但是,您可以使用OnAuthorization
方法访问传递给服务器的所有模型属性,如下所示:
public override void OnAuthorization(AuthorizationContext filterContext)
{
var rawid = filterContext.Controller.ValueProvider.GetValue("id");
if(!string.IsNullOrEmpty(rawid.AttemptedValue))
{
int id = rawid.ConvertTo(typeof(int))
}
// in case that user is unauthorized:
filterContext.Result = new HttpUnauthorizedResult();
}