"Deauthorize" 来自 ActionFilterAttribute 的用户

"Deauthorize" user from ActionFilterAttribute specifically

我正在处理这样一种情况,即我使用 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
                }
            }
        }
    }
}

问题在于 "deauthorizing" 用户,如果他们不以与 [Authorize] 属性相同的方式拥有该记录,通过 returning用户到登录页面。

我知道如何做到这一点的唯一方法是构建自定义 AuthorizeAttribute,但这不允许我访问用户发出请求时传递给该方法的 id 参数。通过使用 ActionFilterAttribute,我可以访问 ActionExecutingContext,我可以使用它来检索参数等。

有没有办法在不使用授权属性的情况下取消用户授权并 return 他们进入登录页面?

应该使用AuthorizeAttribute而不是ActionFilterAttribute。 您无法访问模型的原因是授权在模型绑定器之前运行,因此在执行属性的 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();
}