自定义授权过滤器奇怪行为中的MVC3会话

时间:2011-06-24 08:41:23

标签: asp.net-mvc-3 session action-filter

我们最近从mvc2升级到mvc3,我们的一个自定义授权过滤器(位于ActionResult方法上)似乎构造了一次,但执行了多次。我们知道这一点,因为Filter包含一个错误列表(在构造函数中新建),并且错误被添加到AuthorizeCore上。

自定义过滤器用于检查用户对特定操作方法的访问权限(其级别存储在会话中)

一些代码:

public class SecurityAttribute : AuthorizeAttribute
    {
        public int MinAccessLevel = 1;
        public string UserRole = String.Empty;
        private List<string> _errors;

        public SecurityAttribute()
        {
            _errors = new List<string>();
        }

        public override void OnAuthorization(AuthorizationContext filterContext)
        {

            if (WebSession.AccessLevel < MinAccessLevel)
                _errors.Add("Your access level(" + WebSession.AccessLevel + ") must be " + MinAccessLevel + " or higher");

            if (!String.IsNullOrEmpty(UserRole) && WebSession.UserRole != UserRole)
                _errors.Add("Your User Role must be " + UserRole);

            if (_errors.Any())
            {
                var viewResult = new ViewResult() { ViewName = "SecurityError"};
                viewResult.ViewData.Model = new SecurityErrorViewModel(){Errors = _errors};
                filterContext.Result = viewResult;
            }
        }
    }

这将使用如下:

[HttpPost, Security(MinAccessLevel = 4)]
public ActionResult Complete(int id, string userid){}

视图上的输出(以随机间隔)如此显示(在项目符号列表中)

  • 您的访问级别(6)必须为4或更高
  • 您的访问级别(6)必须为4或更高
  • 您的访问级别(6)必须为4或更高
  • 您的访问级别(6)必须为4或更高

这个问题只在我们升级到mvc3后才会发生,所以我正在寻找有关为什么会发生这种情况或适当修复的任何线索。我已经阅读了关于无会话状态控制器等的各种SO帖子,但这似乎不符合我们面临的情况

谢谢,Mark

1 个答案:

答案 0 :(得分:2)

根据MVC 3发行说明:

  

在以前版本的ASP.NET MVC中,除少数情况外,基于每个请求创建了动作过滤器。这种行为从来都不是保证行为,而只是一个实现细节,而过滤器的合同是将它们视为无状态。在ASP.NET MVC 3中,过滤器被更积极地缓存。因此,任何不正确地存储实例状态的自定义操作过滤器都可能会被破坏。

因此,您不应将错误存储在操作过滤器中。要么直接在OnAuthorization方法中新建列表,要么在其他地方需要访问它们,您可以将它们存储在HttpContext.Items或Session中。