我有自定义过滤器:
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
?
答案 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);
}