Introduction
This article details a way to perform web security much like ASP 2.0 does it, using an ISAPI Filter. Also included in the project is a configuration manager, RemoteScripting framework, base controls for page, text box, and a utilities class. Also included is a rework of Eric Woodruff's Resource Server Handler.
Background
I created this class as a result of a need in my professional work environment for a base framework for web development and security. This is a revised module, and has improvements based on the ASP.NET 2.0 model.
Using the code
To use the security through the ISAPI, it works kind of like how the base ISAPI handler works in the ASP.NET framework. You have to override the machine.config's settings for handling .aspx pages by putting the following items in your <system.web>
section of the web app's web.config file. Note: You do want to have the <authorization><allow users="*" />
section of the config file set to the default settings, since this ISAPI filter does not use .NET security. Since ASP.NET 2.0 contains these features, we simply offer a way to mimic what they are doing. The main difference is that in this module we can support multiple roles in one place mapped to paths and users.
<!---->
<!---->
<httpModules>
<add name="BaseWebSecurity"
type="BaseWeb.HttpModule.BaseSecurityModule,BaseWeb" />
</httpModules>
<httpHandlers>
<add verb="*"
path="BaseWeb.HttpModule.HttpEmbeddedResourceHandler.aspx"
type="BaseWeb.HttpModule.HttpEmbeddedResourceHandler,BaseWeb" />
<add verb="*" path="*.aspx"
type="BaseWeb.HttpModule.PageAuthHandlerFactory,BaseWeb" />
</httpHandlers>
<!---->
<!---->
The configuration file BaseWeb.config should be located in the /bin directory of your application and will contain all your application settings:
<application>
<applicationBrowserSettings
ValidBrowserTypes=
"IE5,IE6x,IEMac5x,Netscape6x,Netscape7x,Opera7x,Mozilla5x" />
<applicationUsers>
<applicationUser name="yourDomain\user"
roles="User" />
<applicationUser name="testmanager"
roles="Manager,Admin" />
<applicationUser name="testAdmin"
roles="Admin" />
</applicationUsers>
<applicationRoles>
<applicationRole type="User" />
<applicationRole type="Manager" />
<applicationRole type="Admin" />
</applicationRoles>
<applicationDirectories>
<applicationDirectory name="root"
path="/TestWebApp/Default.aspx" />
<applicationDirectory name="admin"
path="/TestWebApp/admin/Admin.aspx" />
</applicationDirectories>
<applicationAccessMappings>
<applicationAccessMap role="User"
directory="root" />
<applicationAccessMap role="Manager"
directory="root" />
<applicationAccessMap role="Admin"
directory="admin" />
</applicationAccessMappings>
</application>
As you can see, there are five sections in this config file. The first is for setting the valid browser types for this application. Valid types are: IE5, IE6x, IEMac5x, Netscape6x, Netscape7x, Opera7x, Mozilla5x.
<applicationBrowserSettings
ValidBrowserTypes=
"IE5,IE6x,IEMac5x,Netscape6x,Netscape7x,Opera7x,Mozilla5x" />
The next section is for setting up users. I am using Windows Authentication for this application, you can build a login page that sets the user Identity authentication in a higher level folder, and keep the authentication web module in a lower one where this module and web.config exists.
<applicationUsers>
<applicationUser name="testUser" roles="User" />
<applicationUser name="testmanager" roles="Manager,Admin" />
<applicationUser name="testAdmin" roles="Admin" />
</applicationUsers>
The next section is for setting up application roles. Notice I include three default roles for testing.
<applicationRoles>
<applicationRole type="User" />
<applicationRole type="Manager" />
<applicationRole type="Admin" />
</applicationRoles>
The next section is for setting up application directory paths. I started out with trying to do directories, but I could not find a way to get it to work, so I ended up using precise paths.
<applicationDirectories>
<applicationDirectory name="root"
path="/TestWebApp/Default.aspx" />
<applicationDirectory name="admin"
path="/TestWebApp/admin/Admin.aspx" />
</applicationDirectories>
Note: This was tested on 'localhost' and if the full URL comes across the context.Request.RawUrl
parameter as the full URL, you will have to include that to make the path structure work, as below:
http://www.mysite.com/path/default.aspx
The last section is for setting up application access. This maps roles to directory paths. As you can see, the role name and path name are meshed here to determine each role's access.
<applicationAccessMappings>
<applicationAccessMap role="User" directory="root" />
<applicationAccessMap role="Manager" directory="root" />
<applicationAccessMap role="Admin" directory="admin" />
</applicationAccessMappings>
If you want a role to access multiple paths, you simply enter another <applicationAccessMap>
node in the XML with the new path name and the same role name, thus:
.......
<applicationAccessMap role="Admin" directory="admin" />
<applicationAccessMap role="Admin" directory="root" />
</applicationAccessMappings>
How do we do it in the code? Well, we get the Context User Identity Name parameter (from the current authorized User) which we check in BaseSecurityModule.AuthenticateRequest
, and in SessionHandler.ProcessRequest
we check using the factory class, the user's roles and mappings and compare the current URL from the request to any URL that matches access. If no access is found, we write a generic error page to the Response
.
Points of Interest
I included a lot of other code in here, which I will touch on in other articles. The BrowserSniffer
method is interesting in that it gives you a way to allow only the browsers you want to access the web application. Another feature is a custom global error handler (you see it if you don't have access to a page or if you are using a browser type that is not allowed) that catches error globally and displays a custom error message.
Also there is a Dynamic Scripting platform, which can be used for dynamic page loads without a refresh using JavaScript and a browser that supports IFRAME. I will cover this in a later article.
Some other controls include a textbox with its own validation controls that validates in the BasePage
class, and a BasePage
class that has several useful methods and can be inherited from to give your pages increased functionality. WebUtil has some useful features as well, which I cannot detail here.
You also get a configuration manager file, which is a rework from the code I have been playing with and perfecting for some time.
History
This is my first submission to CodeProject, but this code has served me well in several different revisions in my professional career. I always keep a copy in some revision.