Page view counter

How to Handle Page-by-Page Access Control In ASP.NET?

Rate It (2)

Last post 03-08-2007 12:34 PM by darinsee. 10 replies.

Sort Posts:

  • How to Handle Page-by-Page Access Control In ASP.NET?

    03-07-2007, 8:35 AM
    • Loading...
    • darinsee
    • Joined on 03-04-2007, 6:41 PM
    • United States
    • Posts 85
    • Points 117

    Hello,

    In classic ASP, if I needed to test whether a user was logged in, or member of a valid group (for access control), I'd just create an include page that checked authentication, and group membership (manually validated in database or session).

    Now, in ASP.NET, I'm not sure how to go about doing this - should I just have an include on every page where I want to test group membership & authentication, or just paste the validation code in the Page_Load section of each page I need to test?  Using 2.0's built-in membership and login is not an option, because I'm using Basic Authentication for this app.  Here's a look at how I validate users on a page-by-page basis right now in C# (if this is a bad approach, please let me know!):

    1            if (User.Identity.IsAuthenticated == false)
    2            {
    3                Server.Transfer("unauthorized.aspx?msg=user");
    4            }
    5            else if ((User.IsInRole(@"COMP\GROUP1") == false) && (User.IsInRole(@"COMP\GROUP2") == false))
    6            {
    7                Server.Transfer("unauthorized.aspx?msg=group");
    8            }
    9            else
    10           {
    11               lblUserName.Text = User.Identity.Name;
    12   
    13               if (User.IsInRole(@"COMP\GROUP1"))
    14               {
    15                   lblGroupName.Text = "GROUP1";
    16               }
    17               else if (User.IsInRole(@"COMP\GROUP2"))
    18               {
    19                   lblGroupName.Text = "GROUP2";
    20               }
    21           }
    

    Right now, I have to paste the above code into the Page_Load of every page I want to test - is there a better way to do this with Basic Authentication?

    Thanks!

    Darin

     

  • Re: How to Handle Page-by-Page Access Control In ASP.NET?

    03-07-2007, 10:18 AM
    • Loading...
    • Mr^B
    • Joined on 02-12-2006, 6:38 AM
    • Posts 1,881
    • Points 10,384

    There are several options:

    1. A Web control - which you can create and then use as if it was an include file (they don't work in quite the same way, but will for your example)

    2. An HTTPModule - Implementing IHTTPModule which fires for each and every request that is handled by the asp.net isapi (not page specific).

    3. Master Pages - use a master page with the code in the overriden OnLoad event (personal preference, I hate using the Page_Load event to handle a page load, when there's a perfectly good existing method which you can simply override).


     

    MCSD.Net
  • Re: How to Handle Page-by-Page Access Control In ASP.NET?

    03-07-2007, 10:29 AM
    • Loading...
    • darinsee
    • Joined on 03-04-2007, 6:41 PM
    • United States
    • Posts 85
    • Points 117

    Thanks for the speedy reply Mr^B,

    My sense is that your preferred method (#3) is the way to go - except that I'm unfamiliar with the overridden OnLoad event - I'm figuring that I'd create a new event handler in the code-behind file of the Master Page, and insert my code there?  (I actually tried this in my app's master page, in its code-behind file's Page_Load event, but I got an error saying that "User." (from line 1 in the above code example) was not recognized)  If I may, a few questions about this approach:

    1. Will this overridden OnLoad event in the Master Page override any Page_Load events in pages that use the Master Page as a template?  If so, will all page load events then have to be addressed in the code-behind file of the Master Page?

    2. Where can I learn how to implement an overridden OnLoad event?

    Thanks again,

    Darin
     

  • Re: How to Handle Page-by-Page Access Control In ASP.NET?

    03-07-2007, 10:31 AM
    • Loading...
    • Bhargavi K
    • Joined on 02-27-2007, 10:23 PM
    • Posts 11
    • Points 22

    Hi,

     

    There are several ways to hanlde this. one simple way could be to create a seperate Vb with the above(authentication code)and inherit pages which require authentication from that VB file. In that way you dont have that code pasted in every page_load 

    Hope this solves your problem.

     

    Thanks

    Bhargavi

  • Re: How to Handle Page-by-Page Access Control In ASP.NET?

    03-07-2007, 12:01 PM
    • Loading...
    • darinsee
    • Joined on 03-04-2007, 6:41 PM
    • United States
    • Posts 85
    • Points 117

    Hello Bhargavi,

    In trying to research your suggested approach, I came across the idea of creating a "BasePage" class that inherits System.Web.UI.Page - this class would contain the code in the first posting.  Then, any page that needed to check authentication or make any access restrictions, would need to inherit BasePage instead of System.Web.UI.Page

    Is this still considered a "best practice" approach in .NET 2.0 ?  Most of the info regarding BasePage classes that I found online were referencing .NET 1.1

    So far, it seems like the classic ASP approach of just including a separate file with the above (similar) code, is the easiest and cleanest! :)

    Thanks for any insights on this,

    Darin


     

  • Re: How to Handle Page-by-Page Access Control In ASP.NET?

    03-07-2007, 12:36 PM
    • Loading...
    • darinsee
    • Joined on 03-04-2007, 6:41 PM
    • United States
    • Posts 85
    • Points 117

    Going back to Mr^B's suggestion, here's what I tried:

    1    public partial class AppName_MasterPage : System.Web.UI.MasterPage
    2    {  
    3        protected override void OnLoad(EventArgs e)
    4        {
    5            string strUserName;
    6            string strUserRole;
    7    
    8            if (User.Identity.IsAuthenticated == false)
    9            {
    10               Server.Transfer("unauthorized.aspx?msg=user");
    11           }
    12           else if ((User.IsInRole(@"COMP\GROUP1") == false) && (User.IsInRole(@"COMP\GROUP2") == false))
    13           {
    14               Server.Transfer("unauthorized.aspx?msg=group");
    15           }
    16           else
    17           {
    18               strUserName = User.Identity.Name;
    19               if (User.IsInRole(@"COMP\GROUP1"))
    20               {
    21                   strUserRole = "GROUP1";
    22               }
    23               else if (User.IsInRole(@"COMP\GROUP2"))
    24               {
    25                   strUserRole = "GROUP2";
    26               }
    27           }
    28       }
    29   }
    
    But I when I try to load a page that uses this master page, I get this error:
    CS0103: The name 'User' does not exist in the current context
    (Referencing Line 8 above)
    I feel as though I'm on the verge of a small breakthrough in understanding how to code efficiently (at all?) in .NET - any further help on this would be MUCH appreciated.
    Thanks,
    Darin
     
  • Re: How to Handle Page-by-Page Access Control In ASP.NET?

    03-07-2007, 5:40 PM
    • Loading...
    • darinsee
    • Joined on 03-04-2007, 6:41 PM
    • United States
    • Posts 85
    • Points 117

    I think I may be getting the above error (CS0103: The name 'User' does not exist in the current context) because I'm trying to use "User" in the masterpage, but "User" evidently belongs to the "Page" class, which I don't have access to, because I'm trying to do this in the masterpage - but I need to use "User" in the masterpage, so that I'm able to test for access control on every page that uses the masterpage......

    This feels a bit like a chicken before the egg problem - is there any way to accomplish what I'm trying to do?  Is what I'm trying to do unclear?

    Thanks for any help in advance,

    Darin 

  • Re: How to Handle Page-by-Page Access Control In ASP.NET?

    03-08-2007, 3:43 AM
    Answer
    • Loading...
    • Mr^B
    • Joined on 02-12-2006, 6:38 AM
    • Posts 1,881
    • Points 10,384

    Don't forget to call the base method if you are overriding OnLoad; 

    protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
    
          ....rest of code
    
        }

    And you can access the User via the httpcontext namespace:

    HttpContext.Current.User.Identity

    the User usually forms part of a Page type, but you are using the MasterPage type, which doesn't technically have an httpcontext itself, as it's really a sort of reverse webcontrol that other pages insert into themselves. ie. the page loads the masterpage, not the other way around.


     

    MCSD.Net
  • Re: How to Handle Page-by-Page Access Control In ASP.NET?

    03-08-2007, 10:42 AM
    • Loading...
    • darinsee
    • Joined on 03-04-2007, 6:41 PM
    • United States
    • Posts 85
    • Points 117

    Mr^B, thanks - that did the trick.  For any newbs like me who need all the code, here is what finally worked for me (I stopped using the OnLoad override, just because I don't really know what's going on with that):

    1    public partial class AppName_MainMasterPage : System.Web.UI.MasterPage
    2 {
    3 protected void Page_Load(object sender, EventArgs e)
    4 {
    5 if (HttpContext.Current.User.Identity.IsAuthenticated == false)
    6 {
    7 // Please note that if the page you're transferring to on
    8 // lines 12 and 16 (unauthorized.aspx) is using this master
    9 //
    page, IIS will crash (will begin looping) - make sure that
    10 // the page you transfer to uses a different master page
    11 // or none at all to avoid this problem.
    12 HttpContext.Current.Server.Transfer("unauthorized.aspx?msg=user");
    13 }
    14 else if ((HttpContext.Current.User.IsInRole(@"COMP\Group1") == false) && (HttpContext.Current.User.IsInRole(@"COMP\Group2") == false))
    15 {
    16 HttpContext.Current.Server.Transfer("unauthorized.aspx?msg=group");
    17 }
    18 else 19 {
    20 lblUserName.Text = HttpContext.Current.User.Identity.Name;
    21
    22 if (HttpContext.Current.User.IsInRole(@"COMP\Group1"))
    23 {
    24 lblGroupName.Text = "Group 1 Member";
    25 }
    26 else if (HttpContext.Current.User.IsInRole(@"COMP\Group2"))
    27 {
    28 lblGroupName.Text = "Group 2 Member";
    29 }
    30 }
    31 }
    32 }

    Thanks again,

    Darin

     

  • Re: How to Handle Page-by-Page Access Control In ASP.NET?

    03-08-2007, 10:51 AM
    • Loading...
    • Mr^B
    • Joined on 02-12-2006, 6:38 AM
    • Posts 1,881
    • Points 10,384

    Glad you got it working.

    The OnLoad vs Page_Load is a strange one.  When a page is requested, it makes a call to the page's OnLoad method, which in turn raises the Page_Load event, which you traditionally then handle with the "handles Page_Load" code structure (in VB.Net - in c# you have to rely on AutoEventWireUp and calling your methods on the page by the correct name).

    The problem with this is that it's "rubbish" - a method you know is being run is raising an event which another method is handling...so why not simply override the initial method and save your system from the effort of handling events which you don't NEED to handle.

    It was only at DevWeek2007 (UK) that I picked up on this after it was mentioned in a seminar by Jeff Prosise.

    Granted for most common/garden applications, this is fine - for VERY heavy usage sites it can make quite a bit of difference.
     

    MCSD.Net
  • Re: How to Handle Page-by-Page Access Control In ASP.NET?

    03-08-2007, 12:34 PM
    • Loading...
    • darinsee
    • Joined on 03-04-2007, 6:41 PM
    • United States
    • Posts 85
    • Points 117

    Thanks for the extra details Mr^B - I'm going to have to do so reading up on what it really means to override a method - while I get the idea, I don't know what it means yet, if that makes any sense.  Basically, I think I definitely qualify as a garden app maker for the moment Smile

    In case any one else comes across this post in the future, I've taken this snippet of code one step further, by making my Master Page "strongly typed" for the .aspx pages that use it - basically, the code below, in the master page's code-behind file, allows me to access the authenticated user name and group name within each page that uses the master page.  More on how to do this here: http://msdn2.microsoft.com/en-us/library/ehszf8ax(VS.80).aspx

    Any page that uses the master page must use this tag at the top (I guess that this lets the .aspx page inherit the master page properties & methods (which is added below) ?):
    <%@ MasterType VirtualPath="~/MasterPage.master" %>
    With the above line, now my .aspx file can use Master.strNameUser and Master.strNameGroup to get the values set in the Master Page - definitely something pretty basic for .NET or OOP coders, for this Classic ASP kid, this was a major breakthrough Geeked

    Here is the new code for my master page:

     
    1    public partial class AppName_MasterPage : System.Web.UI.MasterPage
    2    {
    3        // Allows any page using this Master Page access to the currently
    4        // Logged in User's Basic Authentication Name (logic in Page_Init below)
    5        public String strNameUser
    6        {
    7            get { return (String)ViewState["strNameUser"]; }
    8            set { ViewState["strNameUser"] = value; }
    9        }
    10   
    11       // Allows any page using this Master Page access to the currently
    12       // Logged in User's Basic Authentication Group (logic in Page_Init below)
    13       public String strNameGroup
    14       {
    15           get { return (String)ViewState["strNameGroup"]; }
    16           set { ViewState["strNameGroup"] = value; }
    17       }
    18   
    19   	// Set the strNameUser and strNameGroup properties above based on the 
    20   	// user that has logged in with Basic Authentication
    21       void Page_Init(Object sender, EventArgs e)
    22       {
    23           // Set the Logged in User Name Property of this
    24           // strongly-typed MasterPage
    25           this.strNameUser = HttpContext.Current.User.Identity.Name;
    26           lblNameUser.Text = this.strNameUser;
    27   
    28           // Set the Logged in User Group Property of this
    29           // strongly-typed MasterPage
    30           if (HttpContext.Current.User.IsInRole(@"COMPUTERNAME\GROUP1"))
    31           {
    32               this.strNameGroup = "Group 1";
    33               lblNameGroup.Text = this.strNameGroup;
    34           }
    35           else if (HttpContext.Current.User.IsInRole(@"COMPUTERNAME\GROUP2"))
    36           {
    37               this.strNameGroup = "Group 2";
    38               lblNameGroup.Text = this.strNameGroup;
    39           }
    40       }
    41   	
    42   	// Transfer the user away from the page if they haven't logged in
    43   	// (Basic Auth shouldn't let the get that far but..) or if they
    44   	// have logged in, but don't belong to a specified user group on
    45   	// the server.
    46       protected void Page_Load(object sender, EventArgs e)
    47       {
    48           // Please note that if the page you're transferring to on 
    49   		// lines 55 and 59 below (unauthorized.aspx) is using this master 
    50           // page, IIS will crash (will begin looping) - make sure that
    51           // the page you transfer to uses a different master page
    52           // or none at all to avoid this problem.
    53   		if (HttpContext.Current.User.Identity.IsAuthenticated == false)
    54           {
    55               HttpContext.Current.Server.Transfer("unauthorized.aspx?msg=user");
    56           }
    57           else if ((HttpContext.Current.User.IsInRole(@"COMPUTERNAME\GROUP1") == false) && (HttpContext.Current.User.IsInRole(@"COMPUTERNAME\GROUP2") == false))
    58           {
    59               HttpContext.Current.Server.Transfer("unauthorized.aspx?msg=group");
    60           }
    61       }
    62   }
     
    Best, 
    Darin 
     
      
Page 1 of 1 (11 items)