OnAuthorization被多次调用

时间:2015-06-16 16:24:08

标签: c# asp.net-mvc

我有自定义过滤器:

public class SetAuthFilter : IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationContext filterContext)
    {
        //do something
    }
}

Application_Start()下的Global.asax

GlobalFilters.Filters.Add(new SetAuthFilter());

每次调用一个动作时都会调用上述代码。

但是,在我的_Layout.cshtml中,我有2个不同的" BaseController",类似于:

@Html.Action("SomeAction", "Base")
@Html.Action("SomeAction", "Base2")

当我设置一个断点时,似乎SetAuthFilter始终被调用三次,首先是在页面启动之前,然后第二次是在我的断点达到BaseController时,最后是我的断点第三次击中Base2Controller

我应该怎么做才能避免多次调用SetAuthFilter

3 个答案:

答案 0 :(得分:1)

对于每个安全控制器操作,将调用OnAuthorization重载。

如果您不希望这种情况发生,您应该使用AllowAnonymous属性修饰您的函数。

答案 1 :(得分:1)

如果有多个操作与过滤器交互,则无法阻止调用它。每个请求都会调用它。但是,您可以缓存您对该用户身份的最后一次请求,如果是相同的请求,则立即返回而不继续进行较重的授权检查。

public class SetAuthFilter : IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationContext filterContext)
    {
        var key = CreateKey(filterContext);
        var isCached = HttpRuntime.Cache.Get(key);

        if (isCached != null) return;

        HttpRuntime.Cache.Insert(key, true);
        // Heavy auth logic here
    }

    private string CreateKey(AuthorizationContext context)
    {
        // Or create some other unique key that allows you to identify 
        // the same request
        return
            context.RequestContext.HttpContext.User.Identity.Name + "|" +
            context.RequestContext.HttpContext.Request.Url.AbsoluteUri;
    }
}

请注意,这并不考虑空标识或错误的URI。您希望添加一些额外的防御性检查以及缓存失效策略。

这不允许您绕过身份验证,因为仍需要验证每个唯一请求。但是,它最大限度地减少了您调用昂贵的授权逻辑的次数。

答案 2 :(得分:0)

如果您不想在每种方法上调用自定义过滤器: 然后从Global.asax:

下的Application_Start()中删除以下行
GlobalFilters.Filters.Add(new SetAuthFilter());

在那些真正需要授权过滤器的方法和控制器上添加[SetAuth]属性如下:

 [SetAuth]
 public ActionResult Index()
 {
    // your code
    return View(yourModel);
 }