what alternatives are there to using global.asax?

2019-02-05 07:26发布

问题:

I am using my own custom authentication with IIS, and I want the server on every page load (no matter what type of file) to first check the Application variable to see if the user is authenticated and authorized to see the site. In global.asax this could be:

void Application_Start(Object Sender, EventArgs e)
{
  if(Application["username"] == null)
  {
    Response.redirect("login.aspx");
  }
}

The problem is that this site has multiple sub-roots. That is, http://example.com/site1 is a completely different website from http://example.com/site2 . Therefore, I would like said Application_Start function to work on site1 but not affect site2.

If global.asax was customizable at directory level, then this wouldn't be a problem. But since there is only one global.asax per server I cannot implement this solution.

What alternatives are there to global.asax? or can global.asax be different somehow for each directory?

回答1:

HttpModules are an alternative to global.asax

(see also https://www.codeguru.com/csharp/.net/net_asp/article.php/c19389/HTTP-Handlers-and-HTTP-Modules-in-ASPNET.htm
http://codebetter.com/blogs/karlseguin/archive/2006/06/12/146356.aspx )

HttpModules are registered in web.config; which, conveniently, is customizable at directory level. So every directory can have its own unique set of modules (that are inherited in lower directories). All modules have the same functionality as those found in global.asax .

Basically, every page request gets passed through every registered module before it ever gets to the actual page code itself. This happens regardless of what kind of request it is:

"page.aspx"    "page.html"
    |             |
(   |  module 1   |  )
(   |  module 2   |  )
(   |  module 3   |  )
    V             V
(handler 1) (handler 2)

((a much better picture and description can be found at https://www.codeguru.com/csharp/.net/net_asp/article.php/c19389/HTTP-Handlers-and-HTTP-Modules-in-ASPNET.htm ))

So then all you need to do is define your code as a module instead of in global.asax . If the user isn't authenticated, then: response.redirect("login.aspx") will stop control from ever reaching the handler and parsing/returning/running the requested page.

It's a little more complicated than that, so a better description/tutorial can be found at the codeguru website.



回答2:

I'm pretty sure that your code is going to allow access to everybody once a single person logs in - probably not what you want.

According to http://msdn.microsoft.com/en-us/library/ms178473.aspx:

"Called when the first resource (such as a page) in an ASP.NET application is requested. The Application_Start method is called only one time during the life cycle of an application"

Furthermore according to http://support.microsoft.com/kb/307598#1 "Application state variables are, in effect, global variables for each ASP.NET application."

I would suggest you use the built in Membership API and restrict access using the web.config files.

If you are open to using the Membership API rather than rolling your own authentication mechanism, you can use the web.config to check if a user is authorized for a particular folder. You can also relatively simply have the user log in on one site and automatically be logged into the other sites by sharing authentication tickets -- provided they are all on the same root domain.

For sharing authentication tickets see: http://msdn.microsoft.com/en-us/library/ms998288.aspx and http://www.netomatix.com/development/singlesignon.aspx

For how to use the web.config to restrict access: http://www.devhood.com/Tutorials/tutorial_details.aspx?tutorial_id=85



回答3:

Actually I believe there's just one global.asax per asp.net application. If you want example.com/subsite1 to be a different application from example.com/subsite2 you can create two different applications in IIS. As a result they'll run in entirely different application domains (although they may be in the same process (aspnet_wp.exe or w3wp.exe) and even share application pools). As such, if they're different applications they should also get to have independent global.asax files.

To turn a directory into an application. Open IIS->Find the directory/sub site, right click->Properties->Home Directory tab->Click "Create".

For more information on application domains and worker processes, consider reading this blog entry. Hope that helps.