ASP.NET的HTTP模块和处理程序之模块实现

开发 后端
为了实现扩充或扩展Web服务器的功能,ASP.NET提供了HttpHandler(HTTP处理程序)和HttpModule(HTTP模块),这里,笔者将带各位深入了解这些组件的详细信息。这篇文章,笔者将向大家实现一个提供安全服务的HTTP模块。

  实现一个提供安全服务的HTTP模块

  现在我们实现一个HTTP模块,它为我们的Web应用程序提供安全服务。该HTTP模块基本上是提供一种定制的身份认证服务。它将接收HTTP请求中的身份凭证,并确定该凭证是否有效。如果有效,与用户相关的角色是什么?通过User.Identity对象,它把这些角色与访问我们的Web应用程序页面的用户的标识关联起来。

  下面是该HTTP模块的代码:

  1. using System;  
  2. using System.Web;  
  3. using System.Security.Principal;  
  4.  
  5. namespace SecurityModules  
  6. {  
  7.  /// Class1的总体描述。  
  8.  
  9.  public class CustomAuthenticationModule : IHttpModule  
  10.  {  
  11.   public CustomAuthenticationModule()  
  12.   {  
  13.   }  
  14.   public void Init(HttpApplication r_objApplication)  
  15.   {  
  16.    // 向Application 对象注册事件处理程序。  
  17.    r_objApplication.AuthenticateRequest +=   
  18. new EventHandler(this.AuthenticateRequest) ;  
  19.   }  
  20.  
  21.   public void Dispose()  
  22.   {  
  23.    // 此处空出,因为我们不需要做什么操作。  
  24.   }  
  25.  
  26.   private void AuthenticateRequest(object r_objSender,EventArgs r_objEventArgs)  
  27.   {  
  28.    // 鉴别用户的凭证,并找出用户角色。。  
  29.    1. HttpApplication objApp = (HttpApplication) r_objSender ;  
  30.    2. HttpContext objContext = (HttpContext) objApp.Context ;  
  31.    3. if ( (objApp.Request["userid"] == null) ||  
  32.    4.  (objApp.Request["password"] == null) )  
  33.    5.  {  
  34.    6.   objContext.Response.Write("<H1>Credentials not provided</H1>") ;  
  35.    7.   objContext.Response.End() ;  
  36.    8.  }  
  37.  
  38.    9. string userid = "" ;  
  39.    10. userid = objApp.Request["userid"].ToString() ;  
  40.    11. string password = "" ;  
  41.    12. password = objApp.Request["password"].ToString() ;  
  42.    
  43.    13. string[] strRoles ;  
  44.    14. strRoles = AuthenticateAndGetRoles(userid, password) ;  
  45.    15. if ((strRoles == null) || (strRoles.GetLength(0) == 0))  
  46.    16. {  
  47.    17.  objContext.Response.Write("<H1>We are sorry but we could not  
  48. find this user id and password in our database</H1>") ;  
  49.    18.  objApp.CompleteRequest() ;  
  50.    19. }  
  51.  
  52.    20. GenericIdentity objIdentity = new GenericIdentity(userid,  
  53. "CustomAuthentication") ;  
  54.    21. objContext.User = new GenericPrincipal(objIdentity, strRoles) ;  
  55.   }  
  56.  
  57.   private string[] AuthenticateAndGetRoles(string r_strUserID,string r_strPassword)  
  58.   {  
  59.    string[] strRoles = null ;  
  60.    if ((r_strUserID.Equals("Steve")) && (r_strPassword.Equals("15seconds")))  
  61.    {  
  62.     strRoles = new String[1] ;  
  63.     strRoles[0] = "Administrator" ;  
  64.    }  
  65.    else if ((r_strUserID.Equals("Mansoor")) && (r_strPassword.Equals("mas")))  
  66.    {  
  67.     strRoles = new string[1] ;  
  68.     strRoles[0] = "User" ;   
  69.    }  
  70.    return strRoles ;  
  71.   }  
  72.  }  

#p#

  我们研究一下上面的代码

  我们是从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将看到下面的消息:

  

  现在试图使用用户id“Steve”和密码“15seconds”登录系统。输入 http://localhost/webapp2/index.aspx?userid=Steve&password=15seconds你将看到下面的欢迎消息:

 

  

  现在试图使用用户id“Mansoor”和秘码“mas”登录系统。输入http://localhost/webapp2/index.aspx?userid=Mansoor&password=mas你将看到下面的欢迎消息页面:

 

 

  现在试图使用错误的用户id和密码组合来登录系统。输入http://localhost/webapp2/index.aspx?userid=Mansoor&password=xyz你将看到下面的错误消息: 

 

  这表明我们的安全模块在起作用了。你可以通过在AuthenticateAndGetRoles方法中使用数据库访问代码来扩展该安全模块。

  要使所有的部分都起作用,我们必须对web.config文件进行一些修改。首先,由于我们要使用自己的身份验证,因此不需要其它的身份验证机制。为了达到这个目的,改变webapp2的web.config文件中的<authentication>节点,如下所示:

  1. <authentication mode="None"/>  

  类似地,不允许匿名用户访问我们的Web站点。给web.config文件添加下面的语句:

  1. <authorization>  
  2. <deny users="?"/>  
  3. </authorization> 

  用于至少能够匿名访问用于提供凭证的文件。在web.config文件中使用下面的配置设置信息把index.aspx作为***能够匿名访问的文件:

  1. <location path="index.aspx">  
  2.  <system.web>  
  3.   <authorization>  
  4.    <allow users="*"/>  
  5.   </authorization>  
  6.  </system.web>  
  7. </location> 

#p#

  结论

  你可能已经意识到有了HTTP处理程序和模块后,ASP.NET已经给开发者提供了强大的能量。把你自己的组件插入ASP.NET请求处理管道,享受它的优点吧。

  作为练习,你应该进一步改进程序,使示例身份验证模块更加灵活,并能根据用户的需要进行调整。

【编辑推荐】

  1. ASP.NET的HTTP模块和处理程序
  2. ASP.NET的HTTP模块和处理程序之请求的处理过程
  3. ASP.NET的HTTP模块和处理程序之处理程序的执行
  4. ASP.NET的HTTP模块和处理程序之对话状态
  5. ASP.NET的HTTP模块和处理程序之HTTP模块的注册和使用
责任编辑:韩亚珊 来源: 天极网
相关推荐

2011-04-13 15:18:10

.htmHTTP请求处理

2011-04-13 16:49:26

HTTPASP.NET

2011-04-13 16:35:47

HTTPASP.NET

2011-04-13 16:27:48

HTTPASP.NET

2011-04-13 15:50:49

.htmHTTP请求处理

2009-07-20 16:23:01

ASP.NET授权模块

2023-07-04 08:26:15

2023-07-03 08:48:40

Web模块化设计

2009-07-28 15:29:03

实现HTTP请求ASP.NET

2009-07-28 17:17:19

ASP.NET概述

2009-07-27 13:25:15

Postback程序处ASP.NET

2012-08-20 10:24:15

ASP.NET

2023-06-30 14:03:00

ASP.NET模块化设计

2009-07-23 16:20:48

HTTP协议ASP.NET

2009-08-03 11:21:47

ASP.NET编程模型

2009-08-04 11:46:09

2009-08-10 13:32:15

ASP.NET TimASP.NET组件设计

2009-07-20 16:04:37

ASP.NET fra

2009-07-27 12:22:03

ASP.NET和ASPASP.NET入门教程

2011-04-13 14:57:11

ASP.NET请求处理
点赞
收藏

51CTO技术栈公众号