65.9K
CodeProject 正在变化。 阅读更多。
Home

使用应用程序请求路由(Application Request Routing)在 DMZ/多层架构中实现 WCF RIA Services

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.72/5 (13投票s)

2010年9月1日

Ms-PL

7分钟阅读

viewsIcon

46538

这是一篇关于如何使用应用程序请求路由(将 IIS 配置为反向代理)来创建安全的、用于企业的 Silverlight + WCF RIA Services 应用程序的指南!

引言

在大型公司/政府机构/... 中,应用程序架构通常需要遵循一套规则(侧重于可维护性和安全性)。
这些规则可能如下所示:

  • 应用程序需要遵循 多层架构进行开发。
  • 为了安全起见,每一层都应该物理隔离。
  • 只有业务逻辑层可以连接到数据层。
  • 表示层只能连接到业务逻辑层。
  • 表示层不得直接连接到数据层。
  • 表示层位于 DMZ 中,而其他层则受到严格保护。
  • ...

每个项目/公司都会有自己的规则,但概念是相同的。
以下是一个在 ASP.NET 中实现这一目标的示例。

可以看到,要攻击数据层,必须先攻破表示层和业务逻辑层。
您还可以假设在大多数情况下,每一物理层都由防火墙保护。

默认:Silverlight + WCF RIA Services 中的物理层

当您使用 WCF RIA Services 构建 Silverlight 应用程序时,您将获得以下设置:

这仍然是一个三层架构,但表示层运行在客户端。
您可以争论中间层是否算作表示层(因为所有内容都运行在客户端),但我们姑且认为算。

从安全角度来看,这种方式安全性较低。
一旦中间的 Web 服务器被攻破,就可以直接访问数据层。

我们可以添加一个包含一些 WCF 服务的额外层,供我们的 WCF RIA Services 使用,但这会导致代码重复。
这将是一个不受欢迎的副作用,因此我们不认为这是解决我们问题的最佳方案。

分离:一个用于 WCF RIA Services 的额外 Web 应用程序

在我上一篇文章(使用 WCF RIA Services 和普通 .svc 文件可以做的事情)中,我描述了如何分离 Web 应用程序(托管 Silverlight)和服务。从而得到以下设置:

可以看到,我们又前进了一步。我们的服务可以放在一个服务器上,而我们的网页(托管 Silverlight 应用程序)放在另一个服务器上。这确实在物理上分离了我们的层。但问题是 Silverlight 仍然需要直接连接到 WCF RIA Services。

在此设置中,我们的业务逻辑层应该暴露给互联网/位于 DMZ 中/...,以便我们的 Silverlight 客户端访问它。
同样,如果这个服务器被攻破,就可以直接访问数据层!

高级:使用 IIS 应用程序请求路由

有关 ARR 的更多信息,请访问:http://www.iis.net/download/ApplicationRequestRouting
另一个有趣的话题是基于内容的路由:http://hashtagfail.com/post/1000967093/wcf-routing-ria-services 

我们将使用 ARR(结合 URL 重写)因为它允许我们将 IIS 用作反向代理。
通过使用此反向代理,我们将能够实现以下设置:

请按照以下步骤安装和配置 IIS 应用程序请求路由。

A. 准备服务器

  1. 确保您拥有 IIS 7 或 IIS 7.5。
  2. 下载应用程序请求路由扩展:x86 / x64
  3. 安装扩展(它可能会先安装其他扩展)。
  4. 为了测试目的,我们将在一台机器上模拟 2 台服务器。
    为此,请用记事本打开 c:\windows\system32\drivers\etc\hosts

    127.0.0.1 presentationtier
    127.0.0.1 logictier


    我们将使用 IIS 中的主机头(Host Headers)将这些主机名关联起来。

    如果您有 2 台可用于测试的服务器,请使用它们(您可以跳过此步骤)。
    但别忘了安装 WCF RIA Services Toolkit!
  5. 最后,我们将配置应用程序请求路由。
    在 IIS 管理器中,点击您的服务器,然后转到 **应用程序请求路由缓存**。



    重要提示: 如果您使用多台服务器(在实际环境中您会这样做),您需要在表示层(包含 Silverlight 应用程序的 ASP.NET 网站)上执行此操作。

  6. 在右侧选择 **服务器代理设置**,然后勾选 **启用代理** 复选框。

B. 创建业务逻辑层站点

  1. 在 IIS 中,创建一个名为 **LogicSite** 的网站。


    注意,在“绑定”下,“主机名”指向 **logictier**。
    这样,我们就可以模拟该网站配置在 **logictier** 服务器上。
  2. 现在转到应用程序池,打开 **LogicSite** 应用程序池。
    将 .NET Framework 版本更改为 v4.0。

C. 配置业务逻辑层站点

分离 Silverlight+RIA Services 应用程序需要一些操作,您可以在 我上一篇文章 中了解所有细节。
我们将使用那篇文章中的解决方案立即开始。请注意,此解决方案不连接到数据层,它只是使用一个静态列表来模拟。

  1. 下载完整解决方案并解压:Sandworks.Silverlight.nTier.zip (464.99 kb)
  2. 使用 Visual Studio 打开解决方案。
  3. 右键单击项目,然后选择“发布”。

  4. 将发布目标指向正确的目录。

  5. 按 **发布**。
  6. 现在访问 http://logictier/Tasks.svc,您的 WCF RIA Service 应该可以正常工作。

  7. 现在,在站点的根目录下创建一个名为 clientaccesspolicy.xml 的文件,其中包含以下 XML(Silverlight 中跨站点访问所需)。

<?xml version="1.0" encoding="utf-8"?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from http-request-headers="*">
        <domain uri="http://*" />
        <domain uri="https://*" />
      </allow-from>
      <grant-to>
        <resource path="/" include-subpaths="true"/>
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>

这样,我们的业务逻辑层(位于“单独的服务器”上)就已配置并正在工作。

D. 创建表示层(和反向代理)站点

  1. 在 IIS 中,创建一个名为 PresentationSite 的网站。

    注意,“主机名”在“绑定”下指向 presentationtier
    这样,我们就可以模拟该网站配置在 **presentationtier** 服务器上。
     
  2. 现在转到应用程序池,打开 LogicSite 应用程序池。
    将 .NET Framework 版本更改为 v4.0。
     
  3. 对于此应用程序池,请转到 **高级设置**,并将 **空闲超时** 更改为 0 分钟。
    最后,转到 **回收...**,并取消选中 **定期时间间隔(分钟)** 复选框。

E. 配置表示层站点

  1. 返回 Visual Studio,找到 Sandworks.Silverlight.nTier.Client 项目。
  2. 打开 MainPage.xaml.cs
  3. 将其中看到的两个链接都更改为 http://logictier/Tasks.svc
  4. 重新生成整个解决方案。
  5. Sandworks.Silverlight.nTier.Web 站点发布到我们的 PresentationSite


     
  6. 现在,打开以下链接:http://presentationtier/Sandworks.Silverlight.nTier.ClientTestPage.aspx
     
  7. 如果一切顺利,您应该会看到一个 Silverlight 应用程序,并且在您按下“**获取所有任务**”按钮时,您将看到以下内容:

现在,您拥有了一个运行服务的虚拟服务器,以及另一个运行托管 Silverlight 应用程序的实际 Web 应用程序的服务器。
Silverlight 应用程序在本地运行,但仍然连接到 **业务逻辑层**。现在我们已经创建了一个如 **分离**(WCF RIA Services 分离到 2 台服务器)所述的设置。

我们继续。

F. 配置 IIS 应用程序请求路由和 IIS 重写

  1. 打开 PresentationSite(运行在表示层上)的 web.config 文件。
  2. 现在将以下内容添加到配置文件中:

    <system.serviceModel>
       <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
    multipleSiteBindingsEnabled="true" />
    </system.serviceModel>
    <system.webServer>
      <validation validateIntegratedModeConfiguration="false" />
      <rewrite>
       <rules>
         <rule name="Reverse Proxy to Business Logic Tier" stopProcessing="true">
           <match url="^riaservices/(.*)" />
           <action type="Rewrite" url="
    http://logictier/{R:1}" />
         </rule>
       </rules>
      </rewrite>
    </system.webServer>


    这将确保所有请求到 riaservices 路径的请求都被转发到我们的 **logictier** 服务器(包含业务逻辑层)。
     
  3. 现在,访问页面:http://presentationtier/riaservices/Tasks.svc

这样,即使我们访问的是 **presentationtier** 服务器上的页面,它也会显示来自 logictier 服务器的内容。
这意味着我们的 Silverlight 应用程序不再需要与 logictier 服务器通信。因此,我们无需将 **logictier** 服务器暴露给互联网或将其置于 DMZ 中。

注意 1:我们在 LogicSite 中放置的 clientaccesspolicy.xml 文件不再需要。
注意 2:配置中的 system.serviceModel 部分非常重要。如果缺少它,您将收到以下错误:

在您的浏览器中:

服务器在 '/' 应用程序中发生错误。
找不到资源。

在事件查看器中:

WebHost 无法处理请求。
发件人信息:System.ServiceModel.Activation.HostedHttpRequestAsyncResult/27111447
异常:System.Web.HttpException (0x80004005):服务 '/riaservices/Tasks.svc' 不存在。---> System.ServiceModel.EndpointNotFoundException:服务 '/riaservices/Tasks.svc' 不存在。

G. 在我们的 Silverlight 应用程序中的最终结果

  1. 返回 Visual Studio。
  2. 打开 MainPage.xaml.cs
  3. 将两个 URL 都更改为 http://presentationtier/riaservices/Tasks.svc
  4. 重新生成整个解决方案。
  5. 像我们在 **E-5** 中那样发布 Silverlight 应用程序。
  6. 检查 web.config,确保它仍然包含 URL 重写配置。
  7. 访问 http://presentationtier/Sandworks.Silverlight.nTier.ClientTestPage.aspx

我们完成了。

如果您愿意,可以启动 Fiddler,您将看到我们的 Silverlight 应用程序只访问我们的 **presentationtier** 服务器。

经过一篇很长的文章,这是我们取得的成就:

我们的解决方案已准备好投入企业使用!

下载次数

享受..

© . All rights reserved.