IIS 和 ASP.NET 开发服务器之间的核心差异 (VB)

作者 :Scott Mitchell

下载 PDF

在本地测试 ASP.NET 应用程序时,可能使用的是 ASP.NET 开发 Web 服务器。 但是,生产网站很可能是由 IIS 提供支持的。 这些 Web 服务器处理请求的方式存在一些差异,这些差异可能会产生重要后果。 本教程探讨一些更规范的差异。

简介

每当用户访问 ASP.NET 应用程序时,浏览器就会向网站发送请求。 该请求由 Web 服务器软件选取,该软件与 ASP.NET 运行时协调,以生成并返回所请求资源的内容。 I nternet I nformation S ervices (IIS) 是一套服务,可为 Windows 服务器提供基于 Internet 的常见功能。 IIS 是生产环境中最常用于 ASP.NET 应用程序的 Web 服务器;Web 主机提供程序很可能使用 Web 服务器软件来为 ASP.NET 应用程序提供服务。 IIS 也可以用作开发环境中的 Web 服务器软件,但这需要安装 IIS 并对其进行正确配置。

ASP.NET 开发服务器是开发环境的替代 Web 服务器选项;它随附并集成到 Visual Studio 中。 除非 Web 应用程序已配置为使用 IIS,否则 ASP.NET 开发服务器会自动启动,并在首次从 Visual Studio 中访问网页时用作 Web 服务器。 我们在 确定需要部署的文件 教程中创建的演示 Web 应用程序都是未配置为使用 IIS 的基于文件系统的 Web 应用程序。 因此,从 Visual Studio 中访问其中任一网站时,将使用 ASP.NET 开发服务器。

在完美的世界中,开发和生产环境是相同的。 但是,正如我们在前面的教程中讨论的那样,环境具有不同配置设置的情况并不少见。 在环境中使用不同的 Web 服务器软件会增加另一个在部署应用程序时必须考虑的变量。 本教程介绍 IIS 与 ASP.NET 开发服务器之间的主要差异。 由于这些差异,在某些情况下,在开发环境中完美运行的代码会在生产环境中执行时引发异常或行为不同。

安全上下文差异

每当 Web 服务器软件处理传入请求时,它会将该请求与特定安全上下文相关联。 操作系统使用此安全上下文信息来确定请求允许的操作。 例如,ASP.NET 页可能包含将某些消息记录到磁盘上的文件的代码。 为了使此 ASP.NET 页能够顺利执行,安全上下文必须具有相应的文件系统级权限,即对该文件的写入权限。

ASP.NET 开发服务器将传入的请求与当前登录用户的安全上下文相关联。 如果你以管理员身份登录到桌面,则 ASP.NET 开发服务器提供的 ASP.NET 页面将具有与管理员相同的访问权限。 但是,IIS 处理 ASP.NET 请求与特定计算机帐户相关联。 默认情况下,网络服务计算机帐户由 IIS 版本 6 和 7 使用,尽管 Web 主机提供程序可能已为每个客户配置了唯一帐户。 此外,Web 主机提供程序可能已授予此计算机帐户的有限权限。 最终结果是,你可能具有在开发环境中执行且不会出错的网页,但在生产环境中托管时会生成与授权相关的异常。

为了在操作中显示这种类型的错误,我在书评网站中创建了一个页面,用于在磁盘上创建一个文件,用于存储某人查看“ 自学 ASP.NET 24 小时内 3.5” 评论的最近日期和时间。 若要继续操作,请打开页面并将 ~/Tech/TYASP35.aspx 以下代码添加到 Page_Load 事件处理程序:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As  System.EventArgs) Handles Me.Load

    Dim filePath As  String = Server.MapPath("~/LastTYASP35Access.txt")

    Dim contents As  String = String.Format("Last accessed on {0} by {1}", _

                                 DateTime.Now.ToString(), Request.UserHostAddress)

     System.IO.File.WriteAllText(filePath, contents)

End Sub

注意

方法 File.WriteAllText 创建 一个新文件(如果该文件不存在),然后将指定内容写入该文件。 如果文件已存在,则会覆盖其现有内容。

接下来,使用 ASP.NET ASP.NET 开发服务器访问开发环境中的 24 小时 3.5 自学 3.5 书籍复习页。 假设你使用具有在 Web 应用程序的根目录中创建和修改文本文件的足够权限的帐户登录到计算机,书籍评审看起来与以前相同,但每次访问页面时,日期和时间以及用户的 IP 地址都存储在 LastTYASP35Access.txt 文件中。 将浏览器指向此文件;应会看到类似于图 1 所示的消息。

文本文件包含上次访问书评的日期和时间<

图 1:文本文件包含上次访问书籍评审的日期和时间 (单击以查看全尺寸图像)

将 Web 应用程序部署到生产环境,然后访问托管的 “自学 ASP.NET 3.5 in 24 小时 ”书籍审阅页。 此时,应看到书评页面正常或错误消息,如图 2 所示。 某些 Web 主机提供程序向匿名 ASP.NET 计算机帐户授予写入权限,在这种情况下,页面将正常工作,而不会出错。 但是,如果 Web 主机提供程序禁止匿名帐户的写入访问,则UnauthorizedAccessException当页面尝试将当前日期和时间LastTYASP35Access.txt写入文件时,将引发TYASP35.aspx异常。

IIS 使用的默认计算机帐户没有权限写入文件系统

图 2:IIS 使用的默认计算机帐户没有权限写入文件系统 (单击以查看全尺寸映像)

好消息是,大多数 Web 主机提供程序都有某种权限工具,允许你在网站中指定文件系统权限。 向匿名 ASP.NET 帐户授予对根目录的写入访问权限,然后重新访问书籍审阅页面。 (如果需要,请与 Web 主机提供商联系,以获取有关如何向默认 ASP.NET 帐户授予写入权限的帮助。) 这一次,页面应加载且不会出错,并且 LastTYASP35Access.txt 应成功创建文件。

此处的区别在于,由于 ASP.NET 开发服务器在与 IIS 不同的安全上下文下运行,因此,ASP.NET 读取或写入文件系统、从 Windows 事件日志读取或写入 Windows 事件日志或读取或写入 Windows 注册表的页面在开发时可能会按预期工作,但在生产环境中生成异常。 生成将部署到共享 Web 托管环境的 Web 应用程序时,请勿读取或写入事件日志或 Windows 注册表。 另请注意从文件系统读取或写入文件系统的任何 ASP.NET 页面,因为可能需要授予对生产环境中相应文件夹的读取和写入权限。

提供静态内容的差异

IIS 和 ASP.NET 开发服务器之间的另一个核心区别是它们如何处理静态内容请求。 进入 ASP.NET 开发服务器的每个请求(无论是针对 ASP.NET 页、图像还是 JavaScript 文件)都由 ASP.NET 运行时处理。 默认情况下,IIS 仅在请求传入 ASP.NET 资源(例如 ASP.NET 网页、Web 服务等)时调用 ASP.NET 运行时。 对静态内容(图像、CSS 文件、JavaScript 文件、PDF 文件、ZIP 文件等)的请求由 IIS 检索,而不涉及 ASP.NET 运行时。 (可以指示 IIS 在提供静态内容时使用 ASP.NET 运行时;有关详细信息,请参阅本教程中的“使用 IIS 7 对静态文件执行Forms-Based身份验证和 URL 身份验证”部分。)

ASP.NET 运行时执行许多步骤来生成请求的内容,包括身份验证 (标识请求者) 和授权 (确定请求者是否有权) 查看请求的内容。 一种常用的身份验证形式是 基于表单的身份验证,即通过在网页上的文本框中输入用户的凭据(通常是用户名和密码)来标识用户。 验证凭据后,网站会在用户的浏览器中存储 身份验证票证 Cookie,该 Cookie 随后续请求一起发送到网站,用于对用户进行身份验证。 此外,还可以指定 URL 授权 规则来规定用户可以或不能访问特定文件夹的内容。 许多 ASP.NET 网站使用基于表单的身份验证和 URL 授权来支持用户帐户,并定义只有经过身份验证的用户或属于特定角色的用户才能访问的网站部分。

注意

用于对 ASP 进行彻底检查。NET 基于表单的身份验证、URL 授权和其他用户帐户相关功能,请务必检查我的网站安全教程

假设某个网站支持使用基于表单的授权的用户帐户,并且有一个使用 URL 授权的文件夹配置为仅允许经过身份验证的用户。 假设此文件夹包含 ASP.NET 页和 PDF 文件,其意图是只有经过身份验证的用户才能查看这些 PDF 文件。

如果访问者尝试通过直接在其浏览器的“地址”栏中输入 URL 来查看其中一个 PDF 文件,会发生什么情况? 为了找出问题,让我们在书评网站中创建一个新文件夹,添加一些 PDF 文件,并将网站配置为使用 URL 授权来禁止匿名用户访问此文件夹。 如果下载演示应用程序,你将看到我创建了一个名为 PrivateDocs 的文件夹,并从我的 网站安全教程 中添加了 PDF, (如何适合!) 。 该 PrivateDocs 文件夹还包含一个 Web.config 文件,该文件指定拒绝匿名用户的 URL 授权规则:

<?xml version="1.0"?>

<configuration>

    <system.web>

         <authorization>

            <deny  users="?" />

         </authorization>

     </system.web>

</configuration>

最后,我将 Web 应用程序配置为使用基于表单的身份验证,方法是更新根目录中的 Web.config 文件,替换:

<authentication mode="Windows" />

替换为:

<authentication mode="Forms" />

使用 ASP.NET 开发服务器访问站点,并在浏览器的地址栏中输入其中一个 PDF 文件的直接 URL。 如果下载了与本教程关联的网站,URL 应如下所示: http://localhost:portNumber/PrivateDocs/aspnet_tutorial01_Basics_vb.pdf

在地址栏中输入此 URL 会导致浏览器向 ASP.NET 开发服务器发送文件请求。 ASP.NET 开发服务器将请求移交给 ASP.NET 运行时进行处理。 由于尚未登录,并且文件夹中Web.configPrivateDocs的 配置为拒绝匿名访问,因此 ASP.NET 运行时会自动将我们重定向到登录页, Login.aspx (请参阅图 3) 。 将用户重定向到登录页时,ASP.NET 包含一个 ReturnUrl 指示用户尝试查看的页面的 querystring 参数。 成功登录后,用户可以返回到此页面。

未经授权的用户会自动重定向到登录页面

图 3:未经授权的用户会自动重定向到登录页 (单击以查看全尺寸图像)

现在,让我们看看这在生产环境中的行为。 部署应用程序,并输入生产文件夹中某个 PDF PrivateDocs 的直接 URL。 这会提示浏览器为文件发送请求 IIS。 由于请求了静态文件,因此 IIS 会检索并返回该文件,而不会调用 ASP.NET 运行时。 因此,检查没有执行 URL 授权;任何知道文件的直接 URL 的人都可以访问所谓的私有 PDF 的内容。

匿名用户可以通过输入文件的直接 URL 来下载专用 PDF 文件

图 4:匿名用户可以通过输入文件的直接 URL 来下载专用 PDF 文件 (单击以查看全尺寸图像)

使用 IIS 7 对静态文件执行Forms-Based身份验证和 URL 身份验证

可以使用多种技术来保护静态内容免受未经授权的用户。 IIS 7 引入了 集成管道,它将 IIS 的工作流与 ASP.NET 运行时的工作流相结合。 简而言之,可以指示 IIS 调用 ASP.NET 运行时的身份验证和授权模块,所有传入的请求 (包括静态内容(如 PDF 文件) )。 请联系 Web 主机提供商,了解如何将网站配置为使用集成管道。

将 IIS 配置为使用集成管道后,将以下标记添加到 Web.config 根目录中的 文件中:

<system.webServer>

      <modules>

          <add  name="FormsAuthenticationModule"  type="System.Web.Security.FormsAuthenticationModule" />

          <remove  name="UrlAuthorization" />

          <add  name="UrlAuthorization"  type="System.Web.Security.UrlAuthorizationModule" />

          <remove  name="DefaultAuthentication" />

          <add  name="DefaultAuthentication"  type="System.Web.Security.DefaultAuthenticationModule" />

      </modules>

</system.webServer>

此标记指示 IIS 7 使用基于 ASP.NET 的身份验证和授权模块。 重新部署应用程序,然后重新访问 PDF 文件。 这一次,当 IIS 处理请求时,它为 ASP.NET 运行时的身份验证和授权逻辑提供了检查请求的机会。 由于只有经过身份验证的用户才有权查看文件夹中的内容 PrivateDocs ,因此匿名访问者会自动重定向到登录页面, (参考图 3) 。

注意

如果 Web 主机提供程序仍在使用 IIS 6,则无法使用集成管道功能。 一种解决方法是将私有文档放在禁止 HTTP 访问 ((例如 App_Data) )的文件夹中,然后创建一个页面来提供这些文档。 此页面可能名为 GetPDF.aspx,并通过 querystring 参数传递 PDF 的名称。 该 GetPDF.aspx 页面将首先验证用户是否有权查看文件,如果是,将使用 Response.WriteFile(filePath) 方法将请求的 PDF 文件的内容发送回请求客户端。 如果不想启用集成管道,此方法也适用于 IIS 7。

总结

生产环境中的 Web 应用程序是使用 Microsoft 的 IIS Web 服务器软件托管的。 但是,在开发环境中,可以使用 IIS 或 ASP.NET 开发服务器托管应用程序。 理想情况下,应在两个环境中使用相同的 Web 服务器软件,因为使用不同的软件会添加另一个变量。 但是,ASP.NET 开发服务器的易用性使其成为开发环境中的一个有吸引力的选择。 好消息是,IIS 和 ASP.NET 开发服务器之间只有几个基本差异,如果你知道这些差异,你可以采取措施来帮助确保应用程序以相同的方式工作和运行,而不考虑环境。

编程快乐!

深入阅读

有关本教程中讨论的主题的详细信息,请参阅以下资源: