23

I need my users are redirected to AuthError.aspx page ("You don't have the access to this page") in the case when they are authenticated but try to access the page that they cannot access (because of the role for exam). If I set up web.config so:

<authentication mode="Forms">
  <forms loginUrl="~/Account/Login.aspx" timeout="2880" />
</authentication>

this is the system's wrong behaviour because an user is already authenticated and there is no need to redirect him or her to this page. But if I write here AuthError.aspx instead Login.aspx how could I redirect not-yet-authenticated user to the login page?

John Saunders
  • 160,644
  • 26
  • 247
  • 397
mimic
  • 4,897
  • 7
  • 54
  • 93
  • 2
    I feel your pain on this one. I thought it would be easier to do, but I haven't come across a solution for this either. I don't want authenticated yet unauthorized users seeing the login page when they're already logged in. – Ishmael Smyrnow Feb 17 '11 at 15:58
  • Check out this post. http://stackoverflow.com/questions/14731707/redirect-user-to-another-page-from-web-config-when-his-role-has-not-enough-permi?rq=1 – Nishant May 24 '13 at 12:53

6 Answers6

24

On the Page_Load of your login page, you'll want to check if the user is authenticated, and if they are to redirect them to your access denied page:

protected void Page_Load(object sender, EventArgs e)
{
    if (User.Identity.IsAuthenticated) // if the user is already logged in
    {
            Response.Redirect("~/AccessDenied.aspx");
    }
}

If you want to get a little fancier, you can check the ReturnUrl parameter to determine if the user came to the page directly (such as through a bookmark they saved right to the login page) and handle that differently. Here's an example:

protected void Page_Load(object sender, EventArgs e)
    {
        if (User.Identity.IsAuthenticated)
        {

            // if they came to the page directly, ReturnUrl will be null.
            if (String.IsNullOrEmpty(Request["ReturnUrl"]))
            {
                 /* in that case, instead of redirecting, I hide the login 
                    controls and instead display a message saying that are 
                    already logged in. */
            }
            else
            {
            Response.Redirect("~/AccessDenied.aspx");
            }
        }
    }
Joel Beckham
  • 18,254
  • 3
  • 35
  • 58
  • 3
    +1 Coz this solution will work. But is this the best solution ? – Ananth Jan 26 '12 at 15:42
  • Excellent - Worked perfectly. Thanks. – Bob Moss Aug 24 '12 at 15:34
  • It's the best one that I've found so far. – Joel Beckham Feb 19 '13 at 17:56
  • in this case the authenticated user will be redirected to AccessDenied page... but this will apply to all the users. what if I am administrator and I need access to the page ? if I try to access the page then it will redirect me to AccessDenied anyway... !!! – Lucky May 19 '13 at 09:45
  • @Lucky - You could put another check in there to see if the user is an administrator, and if they are, do something else instead of redirecting to the access denied page. – Joel Beckham May 19 '13 at 19:48
  • @Lucky -- Although, the access denied page is only displayed IF the user was redirected to the login page and not if they accessed the page directly. The only reason that a user should be redirected to the login page is if they are not authorized to view the page they requrested. If you're an admin, would there ever be a case where you weren't authorized and therefore redirected to the login page? – Joel Beckham May 19 '13 at 19:50
  • @ Joel Beckham -- ok I got the whole point ... this works good for login page ... in case we try to implement the same concept for other pages that we intend to restrict,say, "changepassword.aspx" then this creates trouble... – Lucky May 25 '13 at 04:52
  • @JoelBeckham I thought about using the same trick, however is there any other way so that we don't have to perform a check on the page-load of every page? – user3437460 Aug 24 '16 at 11:02
2

For me the least hassle most benefit solution to this problem was to create another section (panel) in Login.aspx page with contents to be displayed to users who are authenticated (e.g. logged in) saying "Access denied" instead of the login form. When logged in user hits the page it means they most likely ended up here because they are not authenticated to access the page that redirected them here.

In the login page I use this very simple code to switch visibility of the panel and login form:

if (Request.IsAuthenticated)
{
    LoginUser.Visible = false;
    AccessDeniedPanel.Visible = true;
}

It's dead simple and it works.

Andrew
  • 7,602
  • 2
  • 34
  • 42
Filip
  • 681
  • 7
  • 19
1

You need to:

1) enable roles (in web.config): (replace 'xxx' with your own values)

<roleManager enabled="true">
  <providers>
    <clear />
    <add connectionStringName="ApplicationServices" applicationName="xxx"
      name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" />
    <add applicationName="xxx" name="AspNetWindowsTokenRoleProvider"
      type="System.Web.Security.WindowsTokenRoleProvider" />
  </providers>
</roleManager>

2) you need to restrict access to certain areas of your website for specific roles. I actually answered another question today where I explain how to achieve this. Here is the link

Community
  • 1
  • 1
santiagoIT
  • 9,411
  • 6
  • 46
  • 57
  • Thanks but all these things are done already. Maybe I described wrong but the problem is I use roles and local web config files to protect folders but I don't know how to redirect the user that is trying to access the inaccessible folder to the proper AuthError.aspx page. – mimic Feb 01 '11 at 21:21
1

You need to distinguish between authentication and authorization. Your code snippet addresses the former ("Am I known to this site") but not the latter ("Am I allowed to access this page").

As @santiagoIT suggests, roles may be the best solution to implement the authorization you need. Some controls, such as the LoginView are role-aware and authentication-aware, so you can use these to display different content depending on the role that the user is in.

A common approach is to display different menus to users in the different roles, so that they are only presented with menus which are relevant to their roles - the LoginView is often used for this.

Alternatively you could control the visibility of the content on individual pages, again using the LoginView, so that users who are not authenticate get one messages, those who are authenticated but not allowed to view the page a second message and those who are both authenticated and allowed to view the page see the content.

If you simply want to redirect a user who is authenticated but does not have the required access to view a page, you could also check that the user is the the appropriate role (Roles.IsUserInRole) and redirect to the "You do not have access.." page if not.

If you are really security conscious, you may want to combine the restricted menu/view approach with authorization checking on each page.

SimonF
  • 2,595
  • 2
  • 16
  • 14
  • Thanks for the answer but I prefer to not code this behavior but implement it using web.config. Sure I can check the accessibility inside the behind code but I would like to do that using only web.config. – mimic Feb 01 '11 at 21:22
0

try this :

suppose you need only admin users to access the specified page of yours then in the page_load you could write this :

if (User.Identity.IsAuthenticated)
{
   if ( !User.IsInRole("Admin"))
   {
        Server.Transfer("~/AccessDeniedPage.aspx");
   }

}

and in case you are using routes you could do :

if (User.Identity.IsAuthenticated)
{
   if ( !User.IsInRole("Admin"))
   {
        Response.RedirectToRoute("AccessDeniedRoute");
   }

}
Lucky
  • 203
  • 2
  • 11
-1

You may set a custom error page like this:

<system.web>
  <customErrors mode="On">        
    <error statusCode="403" redirect="AuthError.aspx" />      
  </customErrors>
</system.web>
kolbasov
  • 1,548
  • 11
  • 15
  • 1
    Unfortunately it doesn't work. If I use it it again opens the login page instead just redirecting to the AuthError.aspx =( – mimic Feb 01 '11 at 21:19