views:

2443

answers:

7

How do you solve the infinite login loop problem when you are using cookieless sessions and cannot change the name of login.aspx to a httphandler ?

i.e. When a user with admin rights hits the logout button and the return url to a restricted page is passed to login.aspx then another user without admin rights try's to login they get redirected back to the login page.

I have come across this solution but I cannot change the name of login.aspx to a http handler, and the isauthenticated function doesn't seem to work in the aspx page with cookieless auth because the forms auth ticket seems to be stripped from the url when redirected back to the login page.

EDIT:

Because this application is already in production I cannot alter the page flow of the login/logout/timeout process or rename the login page.

A: 

Could you change the page flow?

What I mean is, rather then redirect back to the login.aspx page when a user does not have access to a resource, redirect them to a information page.

This page explains the reasons for the redirect, and gives them options like:

1. Click here to login as another user.
2. Click here to request access to the page.
3. Click here to login again, if your session has expired.

This would remove the circular reference, and thus the problem.

Bravax
Unfortunately the application is in production already and I cannot change the login procedure, I really need it to be transparent.
Element
I think you might have to make a more fundamental change to the application. Are you unable to release a new version of this with the issue fixed (i.e. by using the httphandler solution)?
Charlie
A: 

A few options...

One, redirect manually back to Login.aspx when a user is logged out, so there is no ReturnURL. Have a meta-refresh on your pages that matches the session timeout so the user doesn't click on resources they suddenly can't get to.

Two, always log someone out in the Page_Load of Login.aspx. Hey, why not? I can think of some reasons, but maybe they don't apply to your situation.

Three, ignore the ReturnURL. You don't have to call RedirectFromLoginPage! Redirect the user to a default landing page on login.

Incidentally, your comment to Bravax's answer (which I thought was good) is somewhat illogical. You are asking, "how do I fix this bug?" and then your reply to a suggested fix is "oh I can't fix this bug." You have a bug in your code... now suck it up and fix it. The problem is the behavior of the application, which you must change. A "transparent" fix would never work, by definition. Perhaps this is the real issue. Probably outside the scope of help from StackOverflow. :)

Bryan
I don't think you understand the question. I need a fix that doesn't alter the flow of forms authentication login/logout, Bravax's solution alters this behavior (I could easily add response.redirect() to the login page if this wasn't the case). Additionally grow up and drop the attitude loser.
Element
He doesn't have an attitude, he's remarking on your comment, which I kind of agree with. You're basically asking for a solution to a problem and already saying that you can't do anything, so, basically, short of magic, there isn't going to be a solution.
Robert C. Barth
A: 

We had a similar problem, and I fixed it doing the following:

If "LogOut".Equals(e.CommandName) Then
    FormsAuthentication.SignOut()
    Response.Redirect("~/Login.aspx")
End If

And then in Login.aspx we change the PostBackUrl to Login.aspx if it contains a ReturnUrl parameter that sends the user back to Login.aspx.

Leandro López
Hi Leandro, this is a good suggestion except it will only work when a user clicks the Logout button, if the users session times out it will still pass the current URL as the returnurl param.
Element
Then again, remove the ReturnUrl parameter in Login.aspx's form postback URL if ReturnUrl contains Login.aspx.
Leandro López
A: 

I agree with the others in an aspect: How can you fix this if you can't modify anything? Are you looking for a solution only altering the web.config file and nothing else?

I truly don't think this is possible

Juan Manuel
#1 this is not an answer. #2 If you took the time to read the question you'll notice it says "cannot alter the page flow of the login/logout/timeout process or rename the login page." it does not say "can't modify anything". I am free to alter any code in the pages just not alter the page flow.
Element
you know, adding a bounty doesn't give you the right to be rude...
Juan Manuel
+1  A: 

Check if the user is authorized to access the page in the returnUrl, after log in on the login.aspx page. You might use this method of the UrlAuthorizationModule (or a custom one if it works best for you):

System.Web.Security.UrlAuthorizationModule.CheckUrlAccessForPrincipal(

     returnUrl,
     userPrincipal, 
     GET");

If the user isn't authorized, just redirect to a page that the user can access.

To get the user Principal:

var roles = System.Web.Security.Roles.GetRolesForUser(username);

var principal = new System.Security.Principal.GenericPrincipal(

   new System.Security.Principal.GenericIdentity(username), 

   roles

);
eglasius
Hi Freddy, this is a good idea except I don't think you can access an authenticated genericprincipal object until the forms ticket has been inserted into the url. Is it possible to get the authenticated principal object in the login page some how ?
Element
I did an edit and added the sample code to get the GenericIdentity.
eglasius
This works for sure, how did it go?
eglasius
A: 

What about adding a http module that checks if the Request.UrlReferrer is the login page and if so checks if they are authorized to access the Request.Url and if not redirects them to a "You are not authorized to view this page." page.

Jonathan Parker
A: 

Although you say you can't change the name of login.aspx to a HTTP handler, have you tried adding a HTTP 301 redirect so that whenever login.aspx is requested the server redirects the user to a HTTP handler e.g. login.ashx?

Ian Oxley