会话在MVC AuthorizeAttribute中变为空 [英] session becoming null in MVC AuthorizeAttribute

查看:67
本文介绍了会话在MVC AuthorizeAttribute中变为空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 AuthorizeAttribute 来检查用户是否设置了18岁以上的年龄Cookie来访问页面.

I am using an AuthorizeAttribute to check that users have an over 18 age cookie set to access pages.

这很好,但是我现在稍作补充. 由于所有视图都使用此属性,因此我正在使用它来允许我及早启动网站. 如果使用添加?VIEWSITE = true到任何URL,它将设置一个Session变量,并允许他们访问该站点.否则,他们将被定向到等待页面.

This works fine, but I am extending in slightly now. As all Views use this Attribute, I am using it to allow me to launch my site early. If uses add ?VIEWSITE=true to any URL, it will set a Session variable, and allow them access to the site. Otherwise, they get directed to a holding page.

这在第一次运行页面时可以正常工作.但是,我在页面上使用输出缓存,并且在下次页面加载时,我的httpcontext.session为空吗?

This works fine first time the page runs. But, I am using output caching on the page, and the next time the page loads, my httpcontext.session is null?

我在属性中添加了一个订单"变量,以确保它们以正确的顺序执行:

I've added an "Order" varible to my attributes to ensure they execute in the correct order:

    [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;

从高速缓存中加载页面后,我是否缺少某些地方可以读取/设置会话变量?

Is there something I am missing here for me to be able to read/set session variables once a page is loaded from cache?

请注意,是httpContext.Session为null,而不是具体为httpContext.Session ["VIEWSITE"]

To be clear, it's httpContext.Session that is null, and not specifically httpContext.Session["VIEWSITE"]

推荐答案

3年后,我遇到了类似的问题.现在我不是专家,但我相信每个控制器上下文调用在其自己的空间中都是唯一的,因此httpContext.Session在新调用中将为null.

3 years down the line and I ran into a similar issue. Now I'm no expert but I believe each controller context call is unique in it's own space, thus httpContext.Session would be null on a new call.

我的问题是以我想存储(具有其自定义应用程序权限)的登录AD用户的形式出现的.我也在扩展AuthorizationAttribute,但是当将此过滤器应用于控制器操作时,即使用户已保存,httpContext还是为null.

My issue came in the form of a logged in AD user I wanted to store (with his custom application permissions) in a session variable. I'm extending on the AuthorizationAttribute too, but when this filter is applied to a controller action, httpContext is null even though the user was saved.

对于那些遇到相同问题的人们,解决方法是创建一个基本控制器,该用户及其会话状态将在其他所有控制器中保留(继承基本控制器).

For people battling with the same issue, the way around this is to create a base controller where this user and it's session state is kept throughout other controllers (inheriting the base controller).

例如.

我的模特:

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

我的基本控制器:

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示例的标准配置):

My HomeController (standard with any MVC example) :

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

            return View();
        }
    }

我的自定义"权限检查过滤器,该过滤器将用于其他任何控制器操作:

My Custom permission checking filter which I'll use on any other controller action:

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()
        {
            ....
        }
    }

这篇关于会话在MVC AuthorizeAttribute中变为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆