The company that I work for is making a transition between classic ASP programs and ASP.NET programs for our intranet software. Eventually, everything will be written in ASP.NET, but because of time constraints, there are still a number of programs that use classic ASP.
To compensate we've written features that allow for redirects and autologins between classic ASP programs and ASP.NET programs. I've been starting to see a problem, though, with holding the session state for our ASP.NET software. If a user uses an ASP.NET program, then does work in a classic ASP program, then goes back to that ASP.NET program, often times, the user's authentication for the ASP.NET program is still in place, yet the user's session is lost, resulting in an error whenever a function is performed within the program.
I'm trying to capture the loss of the session state in global.asax's Session_End event, which would redirect the user to the login page, but that hasn't worked. Has anyone else faced a similar issue with users moving back and forth between classic ASP and ASP.NET and losing sessions? Is that even my real issue here? It's the only thing that I can see as being a problem.
EDIT
This is what we do to redirect users to an ASP.NET page from a classic asp page.
We create an MD5 hash based off of the userID and the date and send it to a redirect.aspx page via the query string. From there, the aspx page creates its own MD5 has based off of the userId and the date, both passed via the query string. If the 2 hashes are identical, the user is authenticated, and the program loads. Here is an example:
Classic ASP:
strDate = Year(Now()) & right("0" & Month(Now()), 2) & right("0" & Day(Now()), 2)
key = MD5(SessionUserID & strDate)
Response.Redirect "/redirect.aspx?key="&key&"&lpid="&ProgramID&"&unum="&SessionUserNum&"&uid="&SessionUserID&"&gid="&SessionGroupID
Redirect.aspx:
string key = Request.QueryString["key"];
//SetDesignModeState Variables:
if (getMd5Hash(Request.QueryString["uid"] + DateTime.Today.ToString("yyyyMMdd")) == key)
{
Session["SessionGroupID"] = Request.QueryString["gid"];
Session["SessionUserNum"] = Request.QueryString["unum"];
Session["SessionUserID"] = Request.QueryString["uid"];
string appID = Request.QueryString["lpid"];
FormsAuthentication.SetAuthCookie(Request.QueryString["uid"], false);
//redirect to ASP.NET page...
I've done a similar thing to you: authenticating users from a legacy ASP application to an ASP.NET site. What would help, is if you could provide a little more detail (sample code, perhaps) of the process you've setup to do this with users coming from the legacy app to the ASPX app.
To give you a brief idea, in my implementation I've done the following:
Create an .ASPX page
The .ASPX page accepts HTTP POST values from a particular legacy ASP app only.
When a POST request is received, I extract the username/password values, then proceed to authenticate in the normal way. If the user is successfully authenticated, we issue a FormsAuthentication cookie to the user.
In reality, my implementation is quite a bit more complicated, using the database as a backing store (as both apps share a common data source) and a particular database field to store a random code which is sent from the classic app to the .NET side to further verify that the request received by the .NET app is valid.
EDIT:
Try manually setting your authentication cookie. Delete the line:
FormsAuthentication.SetAuthCookie(Request.QueryString["uid"], false);
Replace with:
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
Request.QueryString["uid"],
DateTime.Now,
DateTime.Now.AddHours(24),
false,
null)
string encryptedTicket = FormsAuthentication.Encrypt(ticket);
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
HttpContext.Current.Response.Cookies.Add(cookie);
See how you get on with that?
Related
I am managing and old web site (site, not application) that is a hybrid of Web Forms and Classic ASP. The Classic ASP is being phased out, but that is probably a year away. Right now, we are dropping the old form of authentication in favor of Windows Authentication in the web.config.
The problem is that I am attempting to post to a Classic page from the code behind of a web form (http://www.blahsiblah.com/index.aspx) and am getting a 401 error.
var webClient = new WebClient();
var urlClassicASP = "http://www.blahsiblah.com/classic.asp";
var responseArray = webClient.UploadValues(urlClassicASP, "POST", nameValueCollection);
This throws "The remote server returned an error: (401) Unauthorized"
My question is, how can I post to the classic page without invoking the authentication of the dotNet side?
There are multiple ways to achieve this
Here is a simple suggestion that I hope helps
.Net
Use 127.0.0.1 (or your internal 192.169 / 10.1* ) IP to post to the page vs the public URL
Add a parameter (call it 'bypassauth' or something unique ) when sending the request to the ASP page
Add a parameter that identifies the user that you have authenticated in the .Net side
ASP
Find the include where the authentication check is happening and in that check, add another condition before returning 401 that checks two things
1) Request is from local/internal IP
2) Has the bypassauth parameter
3) the user id is valid
This way your old ASP code will still continue to work if requested from a browser and expect user to be authenticated however, when sending the request from .net will let you bypass authentication
I'm sure there are other ideas too, but this is just one approach
My solution was to set:
webClient.UseDefaultCredentials = true;
I have inherited an Classic ASP Site and a "bolt-on" ASP.NET site...
NEITHER are using Authentication, BOTH sides have a manual "reinvent-the- wheel" (hard-coded) security system that validates the user/pw from a SQL 2000 database (i.e. "if the user is found via a SQL SELECT, let them in").
New development is in ASP.NET... and they have "integrated" the two sites via ONE login (described above) on the Classic ASP side... then passing a GUID (saved at the time of login to the users record) they validate the GUID on the ASP.NET side ("yes, this is the correct GUID, therefore this is my user... let them in").
Up until now this has been working ONE DIRECTION (Classic ASP to ASP.NET) only with no issues.
(Getting to the problem, bear with me...)
Now they want to perform the same basic design from ASP.NET to Classic ASP by updating the GUID, passing it back, where the lookup validates the user, send them to the correct Classic ASP page... (so the user can return to the Classic ASP side without re-loging-in, previously required) HOWEVER...
***HERE's THE PROBLEM
Session("UserID") is used on the Classic ASP side to (hard code) validate the user... then Response.Redirect is run to send them back to the page that they previously left via "sRedirectToString" ...
'user is found in DB, so send them to the correct page...
Dim sRedirectToString = 'the correct url
Call Response.Redirect (sRedirectToString)
HOWEVER, Session("UserID") gets cleared by IIS or IE (dun'no) and the (hard-coded) validation fails because Session("UserID") is NULL (blank)
Here's the simple (only) validation:
If Trim(Session("UserID") & "") = "" Then
'Session timed out
Response.Redirect('the denied page)
Else
Response.Write "<meta http-equiv=""X-UA-Compatible"" content=""IE=EmulateIE7"">"
End If
So, why are the Session Variables being cleared by a Redirect? (there is no other system authentication is being used).
There is no Session.Abort, nor any specific coding that is clearing Session("UserID").
But when Session("UserID") is tested (see code above) it is found empty and redirects to the DENIED.asp page.
So, hoping there is some property like "PersistSessionVariables" (or something) that I can set so they don't clear...
BUT THEY DO INDEED CLEAR IMMEDIATELY AFTER THE REDIRECT AND THIS IS CONFUSING TO ME.
I appreciate all the Wizards help!
Recently I have this problem for module by module migration from ASP to ASP.NET. I've already set up a session table in my database for ASP session using after redirected from ASP.NET module. But when I want to use that session ID I already stored, I found a problem. I found that the session ID between this two is different.
For ASP it looks like 342417338 while for ASP.NET it looks like qvc0i13jvmzce3ny5jzxpaci
Is there any way to convert that session ID from ASP.NET to ASP and vice versa?
IF you are passing from asp.net to asp thenEncode your session value and pass with the help of query string and catch this session value at page level and decode using some encode and decode methods.
if your passing from asp to asp.net in global.asax page in session_start method you can catch by using session cokies. like some example I am giving u can follow it
if (null == Request.Cookies["SessionCookie"])
{
Session.Abandon();
Response.Redirect("../../aspx/login/login.aspx");
}
else //if the user is in session get the userid from guid.
{
Session["UserId"] =Request.Cookies["SessionCookie"].Value//this value ucan get as GUID from the url and u can decode
}
ASP and ASP.NET sessions are not shareable.
We would need something intermediate so that there is minimal
rewriting of code.
We should be able to uniquely identify each client's session.
Check this Code Project Post.
We use Sharepoint 2007 as our internal portal. I'm currently developing a custom app (asp.net MVC2) and I've been asked to have the login process mimic Sharepoint, where a user is initially logged in using SSO but then can opt to logout and provide different credentials.
Any blogs/guides on how to do this?
UPDATE:
Thanks to reflector I was able to find a way to do this, but it doesn't totally work.
First off, I'm testing this on IIS running on my local Windows 7 machine.
I have setup the "LogOff" action to do the following:
var current = System.Web.HttpContext.Current;
var response = current.Response;
object obj2 = current.Items["ResponseEnded"];
if ((obj2 == null) || !((bool)obj2))
{
current.Items["ResponseEnded"] = true;
response.StatusCode = 401;
response.Clear();
response.Write("401 UNAUTHORIZED");
response.End();
}
This partially works. When I click "logOFf" I get prompted for credentials. Oddly enough, when debugging, I can see the method gets called twice (this is an MVC action).
But, even when providing valid credentials I still can't log back in. After the third try I get a 401 page.
My only thought here is somehow it's trying to use Kerberos to authenticate and since I don't have Kerberos setup on this machine it fails. But, when I first access the site from IE it just passes me IE credentials on (the SSO) and everything works fine, so I'm not sure why a second authentication fails.
asp.net membership provider is a great choice. There are a lot of options for authentication methods, based on your question though I think the .net membership provider would be your best bet. If you are using simply windows authentication, even sharepoint has its faults as IE will attempt to change the login back to the windows account user.
http://msdn.microsoft.com/en-us/library/yh26yfzy.aspx
I'm implementing the session sharing structure from this link for an ASP classic site to begin the gradual conversion process to ASP.NET. I'm trying to extend the cookie expiration time so that users do not get signed out of the site when the session expires. At the place where the cookie is created in SessionPage.cs I've added the line in the CreateNewSessionCookie() method:
cookie.Expires = DateTime.Now.AddDays(14);
Now this works fine, however, it only works if the user first visits an ASP.NET page, and then visits the ASP classic pages. It doesn't work if visiting an ASP classic page first (looking at the cookie through firefox confirms that different expiration values are given based on if I visit an ASP or ASP.NET page first.) I'm still a bit fuzzy on the mechanics behind this implementation as I don't have a complete understanding of session and cookie handling. However, I would have thought that the VB6 SessionMgr object is calling the SessionUtility DLL, and thus is using the same code to issue the cookie. I have re-registered the SessionUtility using gacutil, and re-exposed it using regasm. How else is the cookie being issued when a user accesses an ASP classic page? How can I change the expiration time?
This might be a total hack, but since you don't have any answers yet...
Iterate through the Request.Cookies collection in classic asp and find the session cookie (you should be able to figure out which one it is fairly easily). Then reissue that cookie Response.Cookies(sessioncookiename) = sessioncookievalue and set
Response.Cookies(sessioncookiename).Expires = Now() + 14