Redirecting Users: Please Help.

J

Jonathan Wood

I've spent days trying to come up with a solution. I'd appreciate it if
anyone can help.

My site requires all users to log on. There are three different roles of
users, and each user type will have access to a completely different set of
pages. "Client" pages are in the root folder and "Admin" and "Trainer" pages
each have their own subfolders.

The problem is that when a user goes to the domain, I want to redirect
"Admin" and "Trainer" users to the appropriate subfolder.

I tried to redirect users in response to the LoggedIn event handler for the
Login control (even though the Roles object has not been initialized then).
That works but if the user clicks the "remember me" box, they can come back
to the site, still logged in, without firing this event.

So I tried to put code in /Default.aspx to test for "Admin" or "Trainer"
users but, since these users don't have access to /Default.aspx, that code
never runs for these users.

So then I tried something like the following:

protected void Application_PostAcquireRequestState(object sender, EventArgs
e)
{
string url = HttpContext.Current.Request.RawUrl;

if (url.EndsWith("Default.aspx", StringComparison.OrdinalIgnoreCase))
{
switch (Users.GetRole())
{
case Users.UserRoles.RoleAdmin:
HttpContext.Current.Server.Transfer("~/Admin/Default.aspx");
break;
case Users.UserRoles.RoleTrainer:
HttpContext.Current.Server.Transfer("~/Trainer/Default.aspx");
break;
}
}
}

Note: Users.GetRole is a custom routine and works when called.

This approach is just plain messy. It's hard to determine exactly when the
user is actually being taken to the default page. If they haven't logged on,
ASP.NET will be redirecting the user to my login page. Then, when I click
"logout," it prevents the page being redirected to the login page. I just
can't seem to make this work reliably.

Any suggestions?

Thanks.
 
K

Kevin Spencer

It seems to me that there's a flaw in your requirement. I would think that
when the user goes to the Home Page initially, you might want to redirect
them, but that they may want to come back to a different page (perhaps
bookmarked) at another time. So, I would think that when the user initially
logs in, you may want to redirect them, and the only other time you might
want to redirect them is when they initially visit the home page. In that
case, if they have a Cookie, you just check to Referer of the Request to see
if they have come from another domain or just started up their browser. If
the HttpReferer is within the domain, you would not want to redirect them.

--
HTH,

Kevin Spencer
Chicken Salad Surgeon
Microsoft MVP
 
J

Jonathan Wood

Kevin,
It seems to me that there's a flaw in your requirement. I would think that
when the user goes to the Home Page initially, you might want to redirect
them, but that they may want to come back to a different page (perhaps
bookmarked) at another time. So, I would think that when the user
initially logs in, you may want to redirect them, and the only other time
you might want to redirect them is when they initially visit the home
page.

I'm sorry but I don't understand this reply at all. How does any of this
conflict with my requirements? The code in my last solution only redirects
them if the home page is being requested. Perhaps you are thinking about the
solution that redirects them once they've logged in. My requirements would
be happy to only redirect them when they go to the home page initially. The
problem is I've found no way to reliably do that.
In that case, if they have a Cookie, you just check to Referer of the
Request to see if they have come from another domain or just started up
their browser. If the HttpReferer is within the domain, you would not want
to redirect them.

Since I'm new to ASP.NET, I'm not familiar with this but will look into it.
It certainly raises a number of questions in my mind (What happens if they
don't have a cookie? When accessing the home and being redirected by ASP.NET
to my login page, does the referrer show the page they were redirected from
or the page they had previously? And what happens if the browser is opened
to my page--there is no referrer page?)

Thanks.
 
S

Scott Roberts

Hi Jonathan,

Actually, the "Remember Me" box only remembers their username. If they close
their browser, open a new one, and return to your site they will still have
to log in again. The aspnet Membership cookie is only valid for one browser
session.

The problem, then, is if they don't close the browser at all. Presumably
they are navigating away from your site then navigating back without closing
their browser. I also presume that the method they are using to navigate
back is taking them to a page that they are not allowed to view.

So, I think that the problem you really have is "What do I do if a user
tries to navigate to a page they are not allowed to view?"

Well, obviously the first step is to NOT link them to a page they can't
view. If the "Default.aspx" page at the root of your domain is secured
against some users, then I'd say you should reconsider that design. Maybe
something like this:

/Default.aspx - No security. Auto-redirect if already logged in?
/Admins/Default.aspx - Admin role only.
/Trainers/Default.aspx - Trainer role only.
/Other/Default.aspx - Pages for both admins & trainers??
etc...

That still doesn't stop users from typing whatever the heck they want in the
address bar, so you still need to handle those errors. I'm guessing you have
a default exception page:

global.asax:

void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
Server.Transfer("~/UnexpectedError.aspx");
}

So in the page load of "UnexpectedError.aspx" you could check
Server.GetLastError() and if it's a security exception simply redirect to
the default page for their role.

Scott
 
J

Jonathan Wood

Scott,
Actually, the "Remember Me" box only remembers their username. If they
close their browser, open a new one, and return to your site they will
still have to log in again. The aspnet Membership cookie is only valid for
one browser session.

That's not what it appears to do for me. First off, it does not remember my
user name after being checked. And when I do check it, I can close the
browser, and when I run it again, no login is needed. (This is running it
from Visual Studio.)
The problem, then, is if they don't close the browser at all. Presumably
they are navigating away from your site then navigating back without
closing their browser. I also presume that the method they are using to
navigate back is taking them to a page that they are not allowed to view.

Or just if there is any circumstance where they could connect without having
to logon.
Well, obviously the first step is to NOT link them to a page they can't
view. If the "Default.aspx" page at the root of your domain is secured
against some users, then I'd say you should reconsider that design. Maybe
something like this:

/Default.aspx - No security. Auto-redirect if already logged in?
/Admins/Default.aspx - Admin role only.
/Trainers/Default.aspx - Trainer role only.
/Other/Default.aspx - Pages for both admins & trainers??
etc...

I've thought about this. I guess it's one option. Most users fall into the
category of Clients and so I wanted them to have the root folder. I'll give
this some more thought though.
That still doesn't stop users from typing whatever the heck they want in
the address bar, so you still need to handle those errors. I'm guessing
you have a default exception page:

global.asax:

void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
Server.Transfer("~/UnexpectedError.aspx");
}

So in the page load of "UnexpectedError.aspx" you could check
Server.GetLastError() and if it's a security exception simply redirect to
the default page for their role.

Right. I'm not too worried about showing an error in the case where they
type in a page they aren't allowed to view.

Thanks.
 
S

Scott Roberts

Jonathan Wood said:
That's not what it appears to do for me. First off, it does not remember
my user name after being checked. And when I do check it, I can close the
browser, and when I run it again, no login is needed. (This is running it
from Visual Studio.)

My apologies, you appear to be exactly correct.
I've thought about this. I guess it's one option. Most users fall into the
category of Clients and so I wanted them to have the root folder. I'll
give this some more thought though.

I always hate it when people try to change my design instead of help me
solve my problem, so I hesitate to answer other people's questions in that
manner. However, in this case, I really think you'll save yourself a lot of
headaches by creating a "Client" sub-folder. It not only solves your
auto-login problem but also your shared images/css problem.
 
I

Ian Semmel

I'm probably the last person to give advice but anyway.

I have a session variable "LoggedIn" which I explicitly set when the
user logs in (and unset when they logout)

In my MASTER page, in the OnLoad handler (there is probably a better
place to do this) :
- If "LoggedIn" is false AND AppRelativeCurrentExecutionFilePath !=
Default.aspx, I redirect to Default.aspx

In Default.aspx OnLoad
- If logged in is true, I redirect to AdminHome.aspx, UserHome.aspx etc
depending on Role.

There is actually a bit more to it as I am using a MySql Membership
Provider but this seems to work.
 
J

Jonathan Wood

Scott,
My apologies, you appear to be exactly correct.

Personally, I've found the default functionality of that box confusing.
I always hate it when people try to change my design instead of help me
solve my problem, so I hesitate to answer other people's questions in that
manner. However, in this case, I really think you'll save yourself a lot
of headaches by creating a "Client" sub-folder. It not only solves your
auto-login problem but also your shared images/css problem.

Well, I'm new enough to ASP.NET that I'm interested in all ideas. In some
ways, it's not as clean a design, but you're right, in solves a number of
problems nicely.

Thanks.
 
J

Jonathan Wood

Ian,
I have a session variable "LoggedIn" which I explicitly set when the
user logs in (and unset when they logout)

In my MASTER page, in the OnLoad handler (there is probably a better
place to do this) :
- If "LoggedIn" is false AND AppRelativeCurrentExecutionFilePath !=
Default.aspx, I redirect to Default.aspx

In Default.aspx OnLoad
- If logged in is true, I redirect to AdminHome.aspx, UserHome.aspx etc
depending on Role.

There is actually a bit more to it as I am using a MySql Membership
Provider but this seems to work.

As currently implemented, this wouldn't work for me because the roles that
need to be redirected do not have access to Default.aspx, and the code could
never run.

Thanks.
 
K

Kevin Spencer

Hi Jonathan,

The HttpRequest.UrlReferer property contains the Uri of the Referer. And
yes, if they have just opened their browser there will be no referer.

--
HTH,

Kevin Spencer
Chicken Salad Surgeon
Microsoft MVP
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top