ASP.NET中的HTTP模块和处理程序 4
 除了这些事件之外,我们还可以使用四个事件。我们可以通过实现Web应用程序的global.asax文件中一些方法来使用这些事件。 
   
这些事件是:
   
· Application_OnStart
   
当第一个请求到达Web应用程序的时候引发这个事件。
   
· Application_OnEnd
   
准备终止应用程序之前引发这个事件。
   
· Session_OnStart
   
用户对话的第一个请求引发这个事件。
   
· Session_OnEnd
   
放弃对话或者对话超期的时候引发这个事件。
在配置文件中注册HTTP模块
   
当我们建立了HTTP模块并把它复制到Web应用程序的bin目录或者全局部件缓冲(Global Assembly Cache)之后,接下来就应该在web.config或machine.config中注册它了。
   
我们可以使用<httpModules>和<add>节点把HTTP模块添加到Web应用程序中。实际上模块都使用<add>节点列举在<httpModules>和</httpModules>节点之内了。
   
因为配置设置信息是可以继承的,所以子目录从父目录那儿继承配置设置信息。其结果是,子目录可能继承了一些不需要的HTTP模块(它们是父配置信息的一部分);因此,我们需要一种删除这些不需要的模块的方法。我们可以使用<remove>节点;如果我们希望删除从应用程序继承得到的所有HTTP模块,可以使用<clear>节点。
   
下面的代码是添加HTTP模块的一个通用示例:
   
   
   
<httpModules>
<add type="classname, assemblyname" name="modulename" />
<httpModules>
   
   
   
下面的代码是从应用程序中删除HTTP模块的一个通用示例:
   
   
   
<httpModules>
<remove name="modulename" />
<httpModules>
   
   
   
在上面的XML中:
   
· Type属性用类和部件名称的形式指定了HTTP模块的实际类型。
   
· Name属性指定了模块的友好名称。其它应用程序可以使用这个名称来识别HTTP模块。
   
ASP.NET运行时如何使用HTTP模块
   
ASP.NET运行时使用HTTP模块实现某些特殊的功能。下面的片段来自于machine.config文件,它显示了ASP.NET运行时安装的HTTP模块:
   
   
   
<httpModules>
<add name="OutputCache" type="System.Web.Caching.OutputCacheModule"/>
<add name="Session" type="System.Web.SessionState.SessionStateModule"/>
<add name="WindowsAuthentication"
type="System.Web.Security.WindowsAuthenticationModule"/>
<add name="FormsAuthentication"
type="System.Web.Security.FormsAuthenticationModule"/>
<add name="PassportAuthentication"
type="System.Web.Security.PassportAuthenticationModule"/>
<add name="UrlAuthorization"
type="System.Web.Security.UrlAuthorizationModule"/>
<add name="FileAuthorization"
type="System.Web.Security.FileAuthorizationModule"/>
</httpModules>
   
   
   
ASP.NET使用上面一些HTTP模块来提供一些服务,例如身份验证和授权、对话管理和输出缓冲。由于这些模块都注册在machine.config文件中。
   
实现一个提供安全服务的HTTP模块
   
现在我们实现一个HTTP模块,它为我们的Web应用程序提供安全服务。该HTTP模块基本上是提供一种定制的身份认证服务。它将接收HTTP请求中的身份凭证,并确定该凭证是否有效。如果有效,与用户相关的角色是什么?通过User.Identity对象,它把这些角色与访问我们的Web应用程序页面的用户的标识关联起来。
下面是该HTTP模块的代码:
   
using System;
using System.Web;
using System.Security.Principal;
   
namespace SecurityModules
{
/// Class1的总体描述。
   
public class CustomAuthenticationModule : IHttpModule
{
public CustomAuthenticationModule()
{
}
public void Init(HttpApplication r_objApplication)
{
// 向Application 对象注册事件处理程序。
r_objApplication.AuthenticateRequest +=
new EventHandler(this.AuthenticateRequest) ;
}
   
public void Dispose()
{
// 此处空出,因为我们不需要做什么操作。
}
   
private void AuthenticateRequest(object r_objSender,EventArgs r_objEventArgs)
{
// 鉴别用户的凭证,并找出用户角色。。
1. HttpApplication objApp = (HttpApplication) r_objSender ;
2. HttpContext objContext = (HttpContext) objApp.Context ;
3. if ( (objApp.Request["userid"] == null) ||
4. (objApp.Request["password"] == null) )
5. {
6. objContext.Response.Write("<H1>Credentials not provided</H1>") ;
7. objContext.Response.End() ;
8. }
   
9. string userid = "" ;
10. userid = objApp.Request["userid"].ToString() ;
11. string password = "" ;
12. password = objApp.Request["password"].ToString() ;
    
13. string[] strRoles ;
14. strRoles = AuthenticateAndGetRoles(userid, password) ;
15. if ((strRoles == null) || (strRoles.GetLength(0) == 0))
16. {
17. objContext.Response.Write("<H1>We are sorry but we could not
find this user id and password in our database</H1>") ;
18. objApp.CompleteRequest() ;
19. }
   
20. GenericIdentity objIdentity = new GenericIdentity(userid,
"CustomAuthentication") ;
21. objContext.User = new GenericPrincipal(objIdentity, strRoles) ;
}
   
private string[] AuthenticateAndGetRoles(string r_strUserID,string r_strPassword)
{
string[] strRoles = null ;
if ((r_strUserID.Equals("Steve")) && (r_strPassword.Equals("15seconds")))
{
strRoles = new String[1] ;
strRoles[0] = "Administrator" ;
}
else if ((r_strUserID.Equals("Mansoor")) && (r_strPassword.Equals("mas")))
{
strRoles = new string[1] ;
strRoles[0] = "User" ;
}
return strRoles ;
}
}
}
   
我们研究一下上面的代码。
   
我们是从Init函数开始的。这个函数把处理程序的AuthenticateRequest事件插入Application(应用程序)对象的事件处理程序列表中。这将导致引发AuthenticationRequest事件的时候Application调用该方法。
   
我们的HTTP模块初始化之后,我们就可以调用它的AuthenticateRequest方法来鉴别客户端请求。AuthenticateRequest方法是该安全/身份认证机制的核心。在这个函数中:
   
1和2行提取HttpApplication和HttpContext对象。3到7行检测是否没有给我们提供了用户id或密码。如果没有提供,就显示错误信息,请求处理过程终止。
   
9到12行从HttpRequest对象中提取用户id和密码。
   
14行调用一个叫做AuthenticateAndGetRoles的辅助(helper)函数。这个函数主要执行身份验证并决定用户角色。上面的代码采用了硬编码(hard-coded),只允许两个用户使用,但是我们可以扩展这个方法,并添加代码与用户数据库交互操作并检索用户的角色。
   
16到19行检测是否有角色与用户关联。如果没有就意味着传递给我们的凭证没有通过验证;因此该凭证是无效的。因此,给客户端发送一个错误信息,并且请求结束了。
   
20和21行非常重要,因为这两行实际上告诉ASP.NET HTTP运行时已登录用户的身份。这两行成功执行以后,我们的ASPx页面就能够使用User对象访问这些信息了。
   
现在我们看一看这种身份验证机制的运行情况。目前我们只允许下面两个用户登录到系统:
   
· User id = Steve, Password = 15seconds, Role = Administrator
· User id = Mansoor, Password = mas, Role = User
   
注意用户id和密码是大小写敏感的(区分大小写)。
   
首先试图不提供凭证登录系统,在IE中输入http://localhost/webapp2/index.ASPx将看到下面的消息:
   
 
。
这些事件是:
· Application_OnStart
当第一个请求到达Web应用程序的时候引发这个事件。
· Application_OnEnd
准备终止应用程序之前引发这个事件。
· Session_OnStart
用户对话的第一个请求引发这个事件。
· Session_OnEnd
放弃对话或者对话超期的时候引发这个事件。
在配置文件中注册HTTP模块
当我们建立了HTTP模块并把它复制到Web应用程序的bin目录或者全局部件缓冲(Global Assembly Cache)之后,接下来就应该在web.config或machine.config中注册它了。
我们可以使用<httpModules>和<add>节点把HTTP模块添加到Web应用程序中。实际上模块都使用<add>节点列举在<httpModules>和</httpModules>节点之内了。
因为配置设置信息是可以继承的,所以子目录从父目录那儿继承配置设置信息。其结果是,子目录可能继承了一些不需要的HTTP模块(它们是父配置信息的一部分);因此,我们需要一种删除这些不需要的模块的方法。我们可以使用<remove>节点;如果我们希望删除从应用程序继承得到的所有HTTP模块,可以使用<clear>节点。
下面的代码是添加HTTP模块的一个通用示例:
<httpModules>
<add type="classname, assemblyname" name="modulename" />
<httpModules>
下面的代码是从应用程序中删除HTTP模块的一个通用示例:
<httpModules>
<remove name="modulename" />
<httpModules>
在上面的XML中:
· Type属性用类和部件名称的形式指定了HTTP模块的实际类型。
· Name属性指定了模块的友好名称。其它应用程序可以使用这个名称来识别HTTP模块。
ASP.NET运行时如何使用HTTP模块
ASP.NET运行时使用HTTP模块实现某些特殊的功能。下面的片段来自于machine.config文件,它显示了ASP.NET运行时安装的HTTP模块:
<httpModules>
<add name="OutputCache" type="System.Web.Caching.OutputCacheModule"/>
<add name="Session" type="System.Web.SessionState.SessionStateModule"/>
<add name="WindowsAuthentication"
type="System.Web.Security.WindowsAuthenticationModule"/>
<add name="FormsAuthentication"
type="System.Web.Security.FormsAuthenticationModule"/>
<add name="PassportAuthentication"
type="System.Web.Security.PassportAuthenticationModule"/>
<add name="UrlAuthorization"
type="System.Web.Security.UrlAuthorizationModule"/>
<add name="FileAuthorization"
type="System.Web.Security.FileAuthorizationModule"/>
</httpModules>
ASP.NET使用上面一些HTTP模块来提供一些服务,例如身份验证和授权、对话管理和输出缓冲。由于这些模块都注册在machine.config文件中。
实现一个提供安全服务的HTTP模块
现在我们实现一个HTTP模块,它为我们的Web应用程序提供安全服务。该HTTP模块基本上是提供一种定制的身份认证服务。它将接收HTTP请求中的身份凭证,并确定该凭证是否有效。如果有效,与用户相关的角色是什么?通过User.Identity对象,它把这些角色与访问我们的Web应用程序页面的用户的标识关联起来。
下面是该HTTP模块的代码:
using System;
using System.Web;
using System.Security.Principal;
namespace SecurityModules
{
/// Class1的总体描述。
public class CustomAuthenticationModule : IHttpModule
{
public CustomAuthenticationModule()
{
}
public void Init(HttpApplication r_objApplication)
{
// 向Application 对象注册事件处理程序。
r_objApplication.AuthenticateRequest +=
new EventHandler(this.AuthenticateRequest) ;
}
public void Dispose()
{
// 此处空出,因为我们不需要做什么操作。
}
private void AuthenticateRequest(object r_objSender,EventArgs r_objEventArgs)
{
// 鉴别用户的凭证,并找出用户角色。。
1. HttpApplication objApp = (HttpApplication) r_objSender ;
2. HttpContext objContext = (HttpContext) objApp.Context ;
3. if ( (objApp.Request["userid"] == null) ||
4. (objApp.Request["password"] == null) )
5. {
6. objContext.Response.Write("<H1>Credentials not provided</H1>") ;
7. objContext.Response.End() ;
8. }
9. string userid = "" ;
10. userid = objApp.Request["userid"].ToString() ;
11. string password = "" ;
12. password = objApp.Request["password"].ToString() ;
13. string[] strRoles ;
14. strRoles = AuthenticateAndGetRoles(userid, password) ;
15. if ((strRoles == null) || (strRoles.GetLength(0) == 0))
16. {
17. objContext.Response.Write("<H1>We are sorry but we could not
find this user id and password in our database</H1>") ;
18. objApp.CompleteRequest() ;
19. }
20. GenericIdentity objIdentity = new GenericIdentity(userid,
"CustomAuthentication") ;
21. objContext.User = new GenericPrincipal(objIdentity, strRoles) ;
}
private string[] AuthenticateAndGetRoles(string r_strUserID,string r_strPassword)
{
string[] strRoles = null ;
if ((r_strUserID.Equals("Steve")) && (r_strPassword.Equals("15seconds")))
{
strRoles = new String[1] ;
strRoles[0] = "Administrator" ;
}
else if ((r_strUserID.Equals("Mansoor")) && (r_strPassword.Equals("mas")))
{
strRoles = new string[1] ;
strRoles[0] = "User" ;
}
return strRoles ;
}
}
}
我们研究一下上面的代码。
我们是从Init函数开始的。这个函数把处理程序的AuthenticateRequest事件插入Application(应用程序)对象的事件处理程序列表中。这将导致引发AuthenticationRequest事件的时候Application调用该方法。
我们的HTTP模块初始化之后,我们就可以调用它的AuthenticateRequest方法来鉴别客户端请求。AuthenticateRequest方法是该安全/身份认证机制的核心。在这个函数中:
1和2行提取HttpApplication和HttpContext对象。3到7行检测是否没有给我们提供了用户id或密码。如果没有提供,就显示错误信息,请求处理过程终止。
9到12行从HttpRequest对象中提取用户id和密码。
14行调用一个叫做AuthenticateAndGetRoles的辅助(helper)函数。这个函数主要执行身份验证并决定用户角色。上面的代码采用了硬编码(hard-coded),只允许两个用户使用,但是我们可以扩展这个方法,并添加代码与用户数据库交互操作并检索用户的角色。
16到19行检测是否有角色与用户关联。如果没有就意味着传递给我们的凭证没有通过验证;因此该凭证是无效的。因此,给客户端发送一个错误信息,并且请求结束了。
20和21行非常重要,因为这两行实际上告诉ASP.NET HTTP运行时已登录用户的身份。这两行成功执行以后,我们的ASPx页面就能够使用User对象访问这些信息了。
现在我们看一看这种身份验证机制的运行情况。目前我们只允许下面两个用户登录到系统:
· User id = Steve, Password = 15seconds, Role = Administrator
· User id = Mansoor, Password = mas, Role = User
注意用户id和密码是大小写敏感的(区分大小写)。
首先试图不提供凭证登录系统,在IE中输入http://localhost/webapp2/index.ASPx将看到下面的消息:
 
 。
来源:upschool.com.cn
作者:
关键字:ASP.NET中,HTTP模块,处理程序
发表日期:2006-12-4
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号