How To Pass HttpContext.Current.Session To A Web API

On a recent project, I had a very unusual requirement, the user’s session (from the HTTP Context) should be accessible to an external web API. Although Microsoft does not recommend this practice for several reasons, like:

  • It breaks the RESTFUL architecture of a service by coupling it with a web application
  • The security concerns of passing unneeded data to a service,

It can be done… before you go down this route I would strongly recommend you consider your solutions architecture as it is highly likely there will be a better solution.

There are many ways of passing information between services, parameters, cookies, database calls etc… and if things like security or performance mean anything to you, then passing the HTTP Context should be considered an extreme last resort (I didn’t even use this route in the end)

The underlining point of a Web API is to be RESTFUL. RESTLESS means the web API should be stateless so sharing a session between an API’s and an application breaks this abstraction, by tightly coupling the two things together.

By sharing session, your service becomes stateful and you’ll have issues scaling or sharing later on down the line. This could bite you in the behind if you want to use scale your services server in the future, as each server will need session state to be configured in an identical state.

Basically, if you need a session for validation, pass a token or authorise the request via the clients IP rather than passing session as an option.

Finally, when you pass the HTTP context around you need to consider concurrency. When IIS tries to access a session, it gets locked as session state is exclusive. An exclusive lock means ASP.NET needs to wait for the current request to finish before it can process a subsequent request. If you have client sides requests like ‘Server Sent’, then expect some fun when you have high loads 😛

If you are stuck with legacy code or have no other option, then read on but do not say I did not warn you 🙂

Global.ascx

public class Global : EPiServer.Global
{
private const string WebApiPrefix = "api";
private static string WebApiExecutionPath = String.Format("~/{0}", WebApiPrefix);
protected void Application_Start(object sender, EventArgs e)
{
}
protected void Application_PostAuthorizeRequest()
{
if (IsWebApiRequest())
HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required);
}
private static bool IsWebApiRequest()
{
return HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath != null
&& HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath.StartsWith(WebApiExecutionPath);
}
}

To enable session passing within your application, you need to enable it within your web.config. To do this, you need to enable the SetSessionStateBehavior for any web API request. In the code above in Application_PostAuthorizeRequest we’re checking if the current request is a web API request, if it is, we’re ensuring the session is attached to the request. It’s that simple.

Getting the session from web api

Now session passing is enabled, your HttpContext.Current.Session should be populated. In your web app if you’re still having issues accessing session data you can try manually, using the snippet below:

private HttpSessionStateBase GetSessionForService()
{
var request = HttpContext.Current.Items["MS_HttpRequestMessage"] as HttpRequestMessage;
if (request == null)
return null;
var httpContext = (HttpContextWrapper)request.Properties["MS_HttpContext"];
return httpContext.Session;
}

Conclusion

Today, we have gone over why passing session state to a web API is a bad idea and why it should be avoided. If however there is no other way, then you can enable session passing in your global.ascx

Jon D Jones

Software Architect, Programmer and Technologist Jon Jones is founder and CEO of London-based tech firm Digital Prompt. He has been working in the field for nearly a decade, specializing in new technologies and technical solution research in the web business. A passionate blogger by heart , speaker & consultant from England.. always on the hunt for the next challenge

More Posts

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *