Post requests in dashboard have no Session

Hi,

We are using hangfire (latest version 1.1.1 ) in our application (asp.net MVC 5). We have some logic in the Application_AcquireRequestState event handler inside the Global.asax that checks for some values stored in the Session (HttpSessionState). When the applicaiton recieves Get request from the hangfire dashboard (for example the recurring /stats), the Session (ex. HttpContext.Current.Session) is properly populated.
But, on the other hand, when we trigger some post request - for example manual trigger of some recurring job, the request that is intercepted in the Application_AcquireRequestState event has no Session (the property is null), even though the “ASP.NET_SessionId” cookie is present in the request.Cookies collection.

Has anyone an idea what is the cause of this?

Thanks in advance,
Aleksandar

Hi,
(sorry two lines limitation for a new post) )we’ve got a similar issue with Hangfire 1.4.1, asp.net MVC 5 and a custom HangfireAuthorizationFilter. On most pages the authorization works as expected (authentication mode=“Forms”). However, on some paged (e.g."/jobs/enqueued/default") the Context.Session is null and the Identity.IsAuthenticated = false. Therefore the authorization fails even if the user is logged in correctly (and other parts of the Dashboard are accessible). http://stackoverflow.com/questions/1382791/asp-net-what-to-do-if-current-session-is-null seems to be a starting point for this issue. However, I haven’t had enough time to look deeper into that and any help or further investigations would be appreciated. Sincerely, Robert

I was able to get around this issue by requiring a session to be made for all requests made to the Dashboard URIs.

For MVC5, I had previously created an HTTP Module that validated the user in the OnPreRequestHandlerExecute event, but required a session to exist in order for validation to occur.

// Snippet: Sets HttpContext.Current.User to an IPrincipal object if the user is authenticated
private void OnPreRequestHandlerExecute(object sender, EventArgs eventArgs) {
    var context = ((HttpApplication)sender).Context;
    if (context.Session == null) {
        return;
    }
    // [snip] Login logic
}

However, since certain dashboard URIs did not create a session, the user was not validated and the requests redirected to the login page. To get around this, I had to make sure that a session was created prior to OnPreRequestHandlerExecute being called. The event I used to accomplish this was OnPostAuthorizeRequest. The logic in this handler is simply to check the URI being requested, and if it begins with ~/Dashboard, I require a session be made. (Note: this is also useful if you want to force a session for your WebAPI services when hosting them in IIS).

// Called prior to OnPreRequestHandlerExecute
private void OnPostAuthorizeRequest(object sender, EventArgs eventArgs) {
    var context = ((HttpApplication)sender).Context;
    if (ShouldRequireSession(context.Request)) {
        context.SetSessionStateBehavior(SessionStateBehavior.Required);
    }
}
// Returns true if the request will require a session to be made 
private static bool ShouldRequireSession(HttpRequest request) {
    return request != null
           && request.AppRelativeCurrentExecutionFilePath != null
           && request.AppRelativeCurrentExecutionFilePath.StartsWith("~/Dashboard", StringComparison.InvariantCultureIgnoreCase);
    }

To hook up these events, I just added the following to the Init method of the HTTP module:

public void Init(HttpApplication context) {
    context.PreRequestHandlerExecute += OnPreRequestHandlerExecute;
    context.PostAuthorizeRequest += OnPostAuthorizeRequest;
}