44422

session becoming null in MVC AuthorizeAttribute

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

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.

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")]

Snipit from my Attribute:

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?

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

Answer1:

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.

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).

ex.

My Model:

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

My Base Controller:

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

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); } }

Usage:

public class Some_OtherController : /*PossibleNamespace?.*/ControllerBase { [PermissionAuthorize("somepermission")] // This was a CRUD application thus 1 permission per actionresult public ActionResult ViewWhatever() { .... } }

Recommend

  • MVC JsonNetResult - “dataloss” when serializing List
  • How to load Q library with Require.js?
  • Adding independent aspx/asmx pages into DotNetNuke
  • ConfigurationBuilder not working in azure function
  • RavenDB indexing errors
  • PyQt4 application on Windows is crashing on exit
  • How to resolve permission denied maybe missing internet permission?
  • jQuery - resize an elements height to match window without refreshing, on window resize
  • Creating PDF from TIFF image using iText
  • SetWindowsHookEx does not react on media keys
  • Angular2 component view does not update on value change via method
  • Access variable of ScriptContext using Nashorn JavaScript Engine (Java 8)
  • How Lists (specifically, RecyclerView with CardViews) in Android work
  • Code in Job's Script Block after Start-Process Does not Execute
  • ActiveRecord query for a count of new users by day
  • Meteor: Do Something On Email Verification Confirmation
  • All Classes Conforming to Protocol Inherit Default Implementation
  • Illegal mix of collations for operation for date/time comparison
  • How to redirect a user to a different server and include HTTP basic authentication credentials?
  • Check if a string to interpolate provides expected placeholders
  • Symfony2: How to get request parameter
  • Build own AppleScript numerical error handling
  • Is there a mandatory requirement to switch app.yaml?
  • File upload with ng-file-upload throwing error
  • ExecuteAsync RestSharp to allow backgroundWorker CancellationPending c#
  • SQL merge duplicate rows and join values that are different
  • AngularJs get employee from factory
  • log4net write single file for each call to log.info
  • Getting error when using KSoap library to consume .NET web services
  • Why joiner is not used after Sequence generator or Update statergy
  • Exception on Android 4.0 `android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode)`
  • File not found error Google Drive API
  • IndexOutOfRangeException on multidimensional array despite using GetLength check
  • LevelDB C iterator
  • Are Kotlin's Float, Int etc optimised to built-in types in the JVM? [duplicate]
  • Is it possible to post an object from jquery to bottle.py?
  • Can't mass-assign protected attributes when import data from csv file
  • Does armcc optimizes non-volatile variables with -O0?
  • Conditional In-Line CSS for IE and Others?
  • How can I use threading to 'tick' a timer to be accessed by other threads?