How to share Session securely between Classic ASP and ASP.NET
by johna | March 22, 2014 | Classic ASP ASP.NET Web Forms Web Development
Looking at the Google search results, it seems that there has been plenty of demand to share Session values between Classic ASP and ASP.NET. This is usually a result of supporting legacy Classic ASP with new development in ASP.NET.
Most of the solutions I found either did not handle sharing securely or required modifications to the Classic ASP code (such as the top ranking Microsoft solution).
Deep into the search results I found what seems like a great solution but doesn't seem to have had much support in the form of comments and social shares.
Like most of the solutions, it uses a Classic ASP script to return requested session variables. But it does this securely by locking down this script to internal requests only (by IP address), and retrieving by a server-side HTTP request. As a server-side request would usually use the user Session of the web server itself rather than the user's Session, the author of this code cleverly retrieves the Classic ASP cookie and passes it in the request headers. A very clever solution.
The only improvement I could suggest is that the IP address could be faked so instead I would possibly suggest using a password protected folder or some other method of authentication.
I also found that when I tried to access the Classic ASP session using the HTTPS protocol it would not work. The only way I could get it to work was to change the IIS setting "New ID On Secure Connect" to false which allows the use of the same Session in both HTTP and HTTPS.
You can find the original solution at http://devproconnections.com/aspnet/share-session-state-between-asp-and-aspnet-apps.
I have used that concept and made my own version that allows you to get or set a Classic ASP Session variable from ASP.NET:
AspSession.cs
/services/aspsession.asp
Update 22-Dec-2017: I've since found there is an issue with this script. Sometimes in Classic ASP there will be multiple session cookies for the same user. I suspect the last one is the one Classic ASP uses. The ASP.NET code needs to be modified to either use the last cookie or try each cookie until it finds one that returns the value. Further investigation and changes are necessary.
Most of the solutions I found either did not handle sharing securely or required modifications to the Classic ASP code (such as the top ranking Microsoft solution).
Deep into the search results I found what seems like a great solution but doesn't seem to have had much support in the form of comments and social shares.
Like most of the solutions, it uses a Classic ASP script to return requested session variables. But it does this securely by locking down this script to internal requests only (by IP address), and retrieving by a server-side HTTP request. As a server-side request would usually use the user Session of the web server itself rather than the user's Session, the author of this code cleverly retrieves the Classic ASP cookie and passes it in the request headers. A very clever solution.
The only improvement I could suggest is that the IP address could be faked so instead I would possibly suggest using a password protected folder or some other method of authentication.
I also found that when I tried to access the Classic ASP session using the HTTPS protocol it would not work. The only way I could get it to work was to change the IIS setting "New ID On Secure Connect" to false which allows the use of the same Session in both HTTP and HTTPS.
You can find the original solution at http://devproconnections.com/aspnet/share-session-state-between-asp-and-aspnet-apps.
I have used that concept and made my own version that allows you to get or set a Classic ASP Session variable from ASP.NET:
AspSession.cs
using System;
using System.IO;
using System.Net;
using System.Web;
public class AspSession
{
public static object Get(string name)
{
HttpContext context = HttpContext.Current;
object value = null;
String[] cookies = context.Request.Cookies.AllKeys;
for (int i = 0; i < cookies.Length; i++)
{
HttpCookie cookie = context.Request.Cookies[cookies[i]];
if (cookie.Name.StartsWith("ASPSESSION"))
{
System.Uri uri = context.Request.Url;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri.Scheme + "://" + uri.Host + ":" + uri.Port.ToString() + "/Services/AspSession.asp?mode=get&name=" + name);
request.Headers.Add("Cookie: " + cookie.Name + "=" + cookie.Value);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
System.Text.Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
StreamReader readStream = new StreamReader(responseStream, encode);
value = readStream.ReadToEnd();
response.Close();
readStream.Close();
break;
}
}
return value;
}
public static void Set(string name, object value)
{
HttpContext context = HttpContext.Current;
String[] cookies = context.Request.Cookies.AllKeys;
for (int i = 0; i < cookies.Length; i++)
{
HttpCookie cookie = context.Request.Cookies[cookies[i]];
if (cookie.Name.StartsWith("ASPSESSION"))
{
System.Uri uri = context.Request.Url;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri.Scheme + "://" + uri.Host + ":" + uri.Port.ToString() + "/Services/LegacySession.asp?mode=set&name=" + context.Server.UrlEncode(name) + "&value=" + context.Server.UrlEncode(value.ToString()));
request.Headers.Add("Cookie: " + cookie.Name + "=" + cookie.Value);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
break;
}
}
}
}
/services/aspsession.asp
<%
Dim strMode, strName, strValue
If Request.ServerVariables("REMOTE_ADDR") = Request.ServerVariables("LOCAL_ADDR") Then
strMode = Request.QueryString("mode")
strName = Request.QueryString("name")
If strMode = "get" Then
Response.Write(Session(strName))
ElseIf strMode = "set" Then
strValue = Request.QueryString("value")
Session(strName) = strValue
End If
End If
%>
Update 22-Dec-2017: I've since found there is an issue with this script. Sometimes in Classic ASP there will be multiple session cookies for the same user. I suspect the last one is the one Classic ASP uses. The ASP.NET code needs to be modified to either use the last cookie or try each cookie until it finds one that returns the value. Further investigation and changes are necessary.
Related Posts
Converting dBase IV programs to run in the browser
by johna | September 13, 2024
Some pointless entertainment trying to get some old dBase programs running in the browser.
How to set up a debugging using the Turnkey Linux LAMP stack and VS Code
by johna | December 19, 2023
The second part in my guide to setting up a website and database using the Turnkey Linux LAMP stack.
How to set up a website and database using the Turnkey Linux LAMP stack
by johna | November 18, 2023
If you need to host your own website for the purposes of web development, Turnkey Linux LAMP Stack is an easy to install all-in-one solution that you can set up on a spare computer or a VM (Virtual Machine).
Comments
by bay | September 2, 2016
Great article!
When session timeout (after 20 minutes), unable to receive cookies anymore. Do you have any suggestion?
Thanks
Nguyen Van Bay
Reply
by John Avis | September 6, 2016
If the Classic ASP session times out then you could modify this code to return an error from the Classic ASP side and have the ASP.NET side redirect to the Classic ASP login page.
That's a good point and I will look at modifying my sample to accommodate this.
Reply
by Nguyen Van Bay | September 7, 2016
Thanks for your reply!
In my case, the home page is an asp page. It contains several links to the aspx pages. When the aspx page is opened from the home page, httpwebrequest hold the Session the same Session of browser. The AspSession.Get method worked well. After 20 minutes ASP session times out, I refreshed home page, the browser still working with old session (not change SessionID), but httpwebrequest create new session. So that, httpresponse returned empty cookiecollection. The AspSession.Get method returned null value.
Do you have any suggestions for me?
Thanks
Nguyen Van Bay
Reply