happyhippy

这个世界的问题在于聪明人充满疑惑,而傻子们坚信不疑。--罗素

工作原理:http://www.microsoft.com/china/technet/security/guidance/secmod37.mspx
URL Rewriting in asp.net:http://msdn2.microsoft.com/en-us/library/ms972974.aspx
在Asp.net中执行URL重写:http://www.microsoft.com/china/msdn/library/webservices/asp.net/URLRewriting.mspx?mfr=true
技巧/诀窍:在asp.net中重写URL:http://blog.joycode.com/scottgu/archive/2007/03/01/94004.aspx
慎用URL重写:http://www.cnblogs.com/csky/archive/2006/08/09/urlrewrite.html





Asp.net管道处理和HttpApplication中的事件处理顺序(From工作原理):

HttpApplication 类的实例是在 ASP.NET 基础结构中创建的,而不是由用户直接创建的。HttpApplication 类的一个实例在其生存期内被用于处理多个请求,但它一次只能处理一个请求。这样,成员变量才可用于存储针对每个请求的数据。

应用程序按照以下顺序执行由 global.asax 文件中定义的模块或用户代码处理的事件:

  1. BeginRequest
  2. AuthenticateRequest
  3. PostAuthenticateRequest
  4. AuthorizeRequest
  5. PostAuthorizeRequest
  6. ResolveRequestCache
  7. PostResolveRequestCache
    PostResolveRequestCache 事件之后、PostMapRequestHandler 事件之前创建一个事件处理程序(对应于请求 URL 的页)。
  8. PostMapRequestHandler
  9. AcquireRequestState
  10. PostAcquireRequestState
  11. PreRequestHandlerExecute
    执行事件处理程序。

     

  12. PostRequestHandlerExecute
  13. ReleaseRequestState
  14. PostReleaseRequestState
    PostReleaseRequestState 事件之后,响应筛选器(如果有)将对输出进行筛选。
  15. UpdateRequestCache
  16. PostUpdateRequestCache
  17. EndRequest







我们应该在哪个事件中重写URL(From《在Asp.net中执行URL重写》):

可以执行 URL 重写的一个安全位置是在 BeginRequest 事件中。也就是说,如果 URL 需要重写,该操作将在任何一个内置 HTTP 模块运行后执行。使用窗体身份验证时,这种方法存在一定的缺陷。如果您以前使用过窗体身份验证,您会了解当用户访问受限资源时,他们将被自动重定向到指定的登录页面。成功登录后,用户将被返回到他们第一次尝试访问的页面。

如果在 BeginRequestAuthenticateRequest 事件中执行 URL 重写,登录页面(提交后)将把用户重定向到重写后的页面上。也就是说,假设用户在其浏览窗口中键入了 /people/ScottMitchell.aspx,此地址将被重写为 /info/employee.aspx?empID=1001。如果将 Web 应用程序配置为使用窗体身份验证,当用户第一次访问 /people/ScottMitchell.aspx 时,首先,URL 将被重写为 /info/employee.aspx?empID=1001;接下来,FormsAuthenticationModule 将运行,并将用户重定向到登录页面(如果需要)。但是,用户在成功登录后将被发送到 /info/employee.aspx?empID=1001,因为当 FormsAuthenticationModule 运行后,此 URL 即是请求的 URL。

同样,在 BeginRequestAuthenticateRequest 事件中执行重写时,UrlAuthorizationModule 看到的将是重写后的 URL。也就是说,如果您在 Web.config 文件中使用 <location> 元素来为特定的 URL 指定授权,则必须引用重写后的 URL。

要解决这些细微问题,您可以决定在 AuthorizeRequest 事件中执行 URL 重写。此方法解决了 URL 授权和窗体身份验证的一些问题,但同时也产生了新的问题:文件授权无法工作。使用 Windows 身份验证时,FileAuthorizationModule 将检查以确保通过身份验证的用户具有访问特定 ASP.NET 页面的相应权限。

假设一组用户对 C:\Inetput\wwwroot\info\employee.aspx 没有 Windows 级别的文件访问权限,并要尝试访问 /info/employee.aspx?empID=1001,他们将会收到授权错误消息。但是,如果我们将 URL 重写移到 AuthenticateRequest 事件中,当 FileAuthorizationModule 检查安全设置时,仍然认为被请求的文件是 people/ScottMitchell.aspx,因为该 URL 必须被重写(感觉这句话有问题,这句话的英文原文:However, if we move the URL rewriting to the AuthenticateRequest event, when the FileAuthorizationModule checks the security settings, it still thinks the file being requested is /people/ScottMitchell.aspx, since the URL has yet to be rewritten。其中的"has yet to be rewriten"语义是指将要被重写但还没有被重写,显然这里就有逻辑错误了,参照上面的HttpApplication事件的触发顺序,我们将 URL 重写移到 AuthenticateRequest 事件中,那么先执行验证请求AuthenticateRequest事件时,就已经把用户请求的url重写成/info/employee.aspx?empID=1001了,所以再下一步授权请求FileAuthorizationModule中,asp.net是对重写后的url:/info/employee.aspx进行文件授权,所以当用户没有Windows级别的文件访问权限时,是不能被检查通过的,也就不存在其中描述的能查看该页面的情况。所以我觉得这句话的英文版本中叙述有误,中文版就错得更离谱了....)。因此,文件授权检查将通过,允许此用户查看重写后的 URL /info/employee.aspx?empID=1001 的内容。

那么,应该何时在 HTTP 模块中执行 URL 重写?这取决于要使用的身份验证类型。
如果不想使用任何身份验证,则无论 URL 重写发生在 BeginRequest、AuthenticateRequest 还是 AuthorizeRequest 中都没有什么关系。
如果要使用窗体身份验证而不使用 Windows 身份验证,请将 URL 重写放在 AuthorizeRequest 事件处理程序中执行。
最后,如果要使用 Windows 身份验证,请在 BeginRequest 或 AuthenticateRequest 事件进行过程中安排 URL 重写.


posted on 2007-08-06 19:32  Silent Void  阅读(1834)  评论(0编辑  收藏  举报