I wrote a short bit about HttpHandlers and HttpModules a couple weeks ago and recently had decided to use an HttpModule to function as a security gateway for specific parts of the application I’m developing.
If you have any experience with ASP.NET, you’ll wonder why I didn’t just use the declarative Forms security. The one shortcoming that I could see of Forms security is that it requires that you only have one form for your application. For example, in your web.config, you’d have something like this:
<authentication mode="Forms">
<forms name=".ASPXAUTH" loginUrl="/login.aspx" />
</authentication>
<authorization>
<allow users="*"/>
</authorization>
and then users that access any directory you protected using the <location path=”administrators”> syntax would be redirected to the /login.aspx script. If you have two different types of users though, each requiring a different login page, you’re stuck. The web.config XML schema only allows you to have one <forms> element per application. I could have split up the applications in IIS, but then I’d have to replicate application settings and libraries to each application’s bin directory. So, long story short, I wrote a short bit of code that authenticates and authorizes users in the Application BeginRequest event. Pseudo code looks like this:
public class SecurityHttpModule : IHttpModule {
// implemented per the interface
public String ModuleName {
get { return "SecurityHttpModule"; }
}
// register for the HttpApplication BeginRequest event
public void Init(HttpApplication application) {
application.BeginRequest += (new EventHandler(this.Application_BeginRequest));
}
// handle the begin request event
private void Application_BeginRequest(Object source, EventArgs e) {
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
// get the user, populate the Thread.CurrentUser...
HttpCookie cookie = context.Request.Cookies.Get(".ASPXAUTH");
if (peanutButterCookie != null) {
FormsAuthenticationTicket fat = FormsAuthentication.Decrypt(cookie.Value);
// get the user & the roles that this user is in using your own logic
string[] roles = User.Roles;
GenericIdentity identity = new GenericIdentity(fat.Name);
GenericPrincipal principal = new GenericPrincipal(identity, roles);
context.User = principal;
}
// find out if the section we're viewing is meant to be secure
// pessimistic: default to forcing a login
Boolean forceLogin = true;
// if the section has security and we're not on the login form for this section
if (s.isSecure() && thisSection.LoginForm != scriptName) {
// groups allowed in this section
ArrayList groups = s.GroupsAllowed();
// loop over all allowed groups, see if this user is in one of those groups
for (int x=0; x
I left out some of the implementation as well as the import statements, so this obviously won't compile if you drop it into your favorite IDE. Couple things to note in this example:
a) the use of GenericPrincipal and GenericIdentity. GenericIdentity is a concrete implementation of the IIdentity interface, that allows you to specify information about the current user. GenericPrincipal is a concrete implementation of the IPrincipal interface, it contains a reference to the GenericIdentity as well as an array of roles that the current user is in, as well as a method to determine is a user is in a specific role. You can choose to use the concrete implementations (like I did in the example above) or you can choose to create your own implementations of those interfaces, adding your own custom properties and methods to your users identities & roles.
b) the HttpContext, which maintains a reference to the current User, which contains the IsInRole() method. Every ASP.NET page can access information about the currently logged in user and what roles this user has.
c) the use of the utility class FormsAuthenticationTicket, which provides the means of creating and reading the values of a forms authentication cookie.
Just for kicks, how does this compare to ColdFusion? In ColdFusion MX (previous versions of CF used SiteMinder, which gives me the shivers), the <cflogin> tag provides similar functionality to the GenericPrincipal and GenericIdentity classes. which you can then use with the IsUserInRole() and getAuthUser() functions. Out of the box it's probably easier to use, but it (in my humble opinion) sacrifices ease of use for extensibility. You can't add additional properties or methods to the logged in user (for instance a last name or a method that returned how long the user has been logged in). Correct me if I'm wrong!
I am currently wrestling with trying to share session state across IIS applications. Could I use this method described above? The goal is to have an enterprise wide security module that would control access to many sites.
Thanks
HI.. interesting thread.. im looking at implementing this kind of thing at the moment, just getting to grips with iprincipal’s etc.. do you have an expanded example with more source?
Cheers
hello
introduce myself simply first…^^
i’m a korean and my job is development program.
i have very poor english..hopefully you understand it please~
reason for this mail is asking something about program.
can you please send programming source if posible to do??
anyway thank for reading my mail~~
IIS is a strange app..