【问题标题】:"Deauthorize" user from ActionFilterAttribute specifically专门从 ActionFilterAttribute 中“取消授权”用户
【发布时间】:2016-01-02 01:58:47
【问题描述】:

我正在处理一个场景,我使用 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,我可以使用它来检索参数等。

有没有办法在不使用授权属性的情况下取消对用户的授权并将其返回到登录页面?

【问题讨论】:

    标签: c# asp.net-mvc authorization custom-attributes action-filter


    【解决方案1】:

    应该使用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();
    } 
    

    【讨论】:

    • 感谢您的帖子。我现在只是在努力将 id 的值转换为我可以使用的值,尝试将其转换为某种 int 类型的尝试都失败了。
    • 您遇到了什么异常?检查 id 不为空的调试器。您可以检查filterContext.HttpContext.Request.Params["id"] 是否存在。我不知道您如何尝试将其转换为 int 但这是这样做的方法:id.ConvertTo(typeof(int))
    • 我能够使用 id.AttemptedValue 进行转换。我将接受这个作为我的答案。您应该编辑它以包含 filterContext.Result = new HttpUnauthorizedResult();返回;不过。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多