сессия становится пустой в MVC AuthorizeAttribute - PullRequest
2 голосов
/ 30 июня 2011

Я использую AuthorizeAttribute , чтобы проверить, что пользователи имеют файлы cookie старше 18 лет, настроенные для доступа к страницам.

Это отлично работает, но сейчас я немного расширяюсь.Поскольку все представления используют этот атрибут, я использую его, чтобы я мог запустить свой сайт раньше.Если для любого URL используется add? VIEWSITE = true, он установит переменную Session и предоставит им доступ к сайту.В противном случае они перенаправляются на удерживающую страницу.

Это отлично работает при первом запуске страницы.Но я использую кэширование вывода на странице, и в следующий раз при загрузке страницы мой httpcontext.session будет иметь значение null?

Я добавил переменную «Порядок» в свои атрибуты, чтобы они выполнялись вправильный порядок:

    [OfAge(Order = 1)]
    [OutputCache(Order = 2, Duration = 2000, VaryByParam = "categoryName")]

сниппит из моего атрибута:

        protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        HttpRequestBase req = httpContext.Request;
        HttpResponseBase res = httpContext.Response;


        DateTime Live_Date = new DateTime(2011, 07, 01, 07, 0, 0);

        if (DateTime.Now > Live_Date || req.QueryString["VIEWSITE"] != null || httpContext.Session["VIEWSITE"] != null)
        {
            httpContext.Session["VIEWSITE"] = true;

Есть ли что-то, чего мне здесь не хватает, чтобы я мог читать / устанавливать переменные сеанса после загрузки страницы изкеш?

Для ясности, это httpContext.Session, который является нулевым, а не конкретно httpContext.Session ["VIEWSITE"]

1 Ответ

1 голос
/ 13 ноября 2014

3 года спустя, и я столкнулся с подобной проблемой.Сейчас я не эксперт, но я считаю, что каждый контекстный вызов контроллера уникален в своем собственном пространстве, поэтому httpContext.Session при новом вызове будет нулевым.

Моя проблема возникла в форме зарегистрированного пользователя AD, которого я хотел сохранить (с его пользовательскими разрешениями приложения) в переменной сеанса.Я также расширяю атрибут AuthorizationAttribute, но когда этот фильтр применяется к действию контроллера, httpContext имеет значение null, даже если пользователь был сохранен.

Для людей, борющихся с той же проблемой, способ обойти этосоздайте базовый контроллер, где этот пользователь и его состояние сеанса сохраняются во всех других контроллерах (наследуя базовый контроллер).

ex.

Моя модель:

public class LoggedInUser
    {
        public somenamespace.userclass UserProfile { get; set; }
        public List<somenamespace.user_permission_class> UserPermissions { get; set; }
    }

MyБазовый контроллер:

public class ControllerBase : Controller
    {
        private LoggedInUser _LoginUser;

        public LoggedInUser LoginUser
        {
            get 
            {
                if (_LoginUser != null)
                    return _LoginUser;

                if (Session["_LoginUser"] == null)
                    return null;

                return Session["_LoginUser"] as LoggedInUser;
            }
            set
            {
                _LoginUser = value;
                Session["_LoginUser"] = _LoginUser;
            }
        }

        public void PerformUserSetup(string sUsername) // sUsername for testing another user, otherwise User.Identity will be used.
        {
            sUsername = string.IsNullOrEmpty(sUsername) ? User.Identity.Name : sUsername;
            sUsername = (sUsername.IndexOf("\\") > 0) ? sUsername.Split('\\').ToArray()[1] : sUsername;

            // Todo - SQL conversion to stored procedure
            List<userclass> tmpUser = Root.Query<userclass>(/*sql to select user*/).ToList();

            List<user_permission_class> tmpUserpermissions = Root.Query<user_permission_class>(/*sql to select user permissions*/).ToList();

            LoggedInUser _LoginUser = new LoggedInUser();
            _LoginUser.UserProfile = tmpUser.First();
            _LoginUser.UserPermissions = tmpUserpermissions;

            LoginUser = _LoginUser;
        }

    }

Мой HomeController (стандартный для любого примера MVC):

public class HomeController : ControllerBase
    {
        [Authorize] // Standard AuthorizeAttribute (AD test)
        public ActionResult Index()
        {
            if (Session["_LoginUser"] == null)
                PerformUserSetup("");

            return View();
        }
    }

Мой пользовательский фильтр проверки разрешений, который я буду использовать для любого другого действия контроллера:

public class PermissionAuthorize : AuthorizeAttribute
    {
        private readonly string[] permissions;
        public PermissionAuthorize(params string[] perms)
        {
            this.permissions = perms;
        }

        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            bool auth = false;

            if (httpContext.Session["_LoginUser"] == null)
            {
                // Do nothing as auth is false.
            }
            else
            {
                // Check permissions and set auth = true if permission is valid.
                auth = true;
            }

            return auth;
        }

        /* not using
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            var tmp = filterContext.HttpContext.Session;
        }
        */
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            // Todo - direct to "unauth page"
            base.HandleUnauthorizedRequest(filterContext);
        }
    }

Использование:

public class Some_OtherController : /*PossibleNamespace?.*/ControllerBase
    {

        [PermissionAuthorize("somepermission")] // This was a CRUD application thus 1 permission per actionresult
        public ActionResult ViewWhatever()
        {
            ....
        }
    }
...