Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determine if user can access the requested page?

I have an ASP.Net website with multiple roles, each with access to a separate directory (i.e. admin users can access /admin, shoppers can access /shop etc), using a shared login page. If someone visits the login page with the return URL set to a directory they do not have access to (e.g. a shopper visits /login.aspx?returnurl=/admin/index.aspx), the user can authentice successfully (the login credentials are valid), but they end up back at the login page (they don't have access to the page they've requested).

How do I pick this up, so I can display a message do the user?

like image 955
user9659 Avatar asked Jun 26 '09 10:06

user9659


3 Answers

UrlAuthorizationModule.CheckUrlAccessForPrincipal()

is what you need to use to test user access to a location (page or folder) ( http://msdn.microsoft.com/en-us/library/system.web.security.urlauthorizationmodule.checkurlaccessforprincipal.aspx )

like image 134
Andrey Avatar answered Oct 27 '22 08:10

Andrey


I ended up doing this in the page_load event of the login page:

if (User.Identity.IsAuthenticated)
{
    LoginErrorDetails.Text = "You are not authorized to view the requested page";
}

The thinking being, if an authenticated user ends up at the login page, they have either been sent their as a result of trying to access an page they are not authorized to view, or they have authenticated and then manually gone to the log in page (unlikely).

A further action would be to send the user to the relevant home page whenever they visit the login page, if they are already authenticated.

like image 44
user9659 Avatar answered Oct 27 '22 10:10

user9659


One approach would be to override OnLoad of your aspx forms and check if the authenticated user is allowed access to the resource based on the role. So you create a BasePage.cs (in which you define a class BasePage which inherits from System.Web.UI.Page) for example from which all your Forms (aspx) inherit, in which you do this:

protected override void OnLoad(EventArgs e)
{
    InitializeSitemap();
    if (SiteMap.CurrentNode != null)
    {
        if (!UrlHelper.IsAnonymousAllowed(SiteMap.CurrentNode) && (!HttpContext.Current.User.Identity.IsAuthenticated || !UrlHelper.IsAccesible(SiteMap.CurrentNode)))
        {
            // You can redirect here to some form that has a custom message
            Response.Redirect("~/Forms/Logout.aspx");

            return;
        }
    }
    base.OnLoad(e);
}

Then in your UrlHelper class you need that IsAccessible function used above:

public static bool IsAccesible(SiteMapNode node)
{
    bool toRole = false;

    foreach (string role in node.Roles)
    {
        if (role == "*" || HttpContext.Current.User.IsInRole(role))
        {
            toRole = true;
        }
    }

    return toRole;
}

Here is IsAnonymousAllowed in case you wondered:

public static bool IsAnonymousAllowed(SiteMapNode node)
{
    return node[AllowAnonymousAttribute] != null ? bool.Parse(node[AllowAnonymousAttribute]) : false;
}
like image 41
tzup Avatar answered Oct 27 '22 10:10

tzup