Web 站点的一个公共需求就是只允许部分成员或其他授权用户才能够查看特殊页面的内容。ASP.NET 角色管理能够基于安全角色对 Web 文件的访问进行限制。网站地图安全调整则能够将网站地图中的导航链接进行隐藏,同样也是基于安全角色。
假设存在下列显示在 ASP.NET 页面中的导航结构。
Home Products Hardware Software Discounts Services Training Consulting Support
通过对 Support.aspx 页面的 ASP.NET 访问规则进行配置,名为 Customer 的非成员客户端角色被限制成不允许查看 Support 页面。
要想在导航显示中隐藏 Support 链接,就应该先对 Web.config 文件中的网站地图提供者进行配置并启用安全调整。因为应用程序会使用 ASP.NET 的 URL 授权和文件授权来隐藏 Support 页面的链接,所以不需要进行额外的工作。ASP.NET 2.0 中的 XmlSiteMapProvider
控件使用 URL 和文件验证为每个网站地图节点进行验证检测。
如果需要针对非 Customer 角色的客户端显示 Support 链接,可以使用 Support.aspx 文件的网站地图节点中的 roles
参数。该参数会扩展使用 URL 验证和文件验证对网站地图节点的访问。
下列代码中为 Customers 角色设置用于 Support 页面访问的 roles
参数。启用安全调整后,该设置允许 Customers 角色的用户访问指向 Support 页面的链接,即使他们没有得到查看实际文件的 URL 授权或文件授权的许可。
<?xml version="1.0" encoding="utf-8" ?> <siteMap> <!-- other <siteMapNode> elements --> <siteMapNode title="Support" description="Support" url="~/Customers/Support.aspx" roles="Customers" /> </siteMap>
如果非 Customers 角色的成员用户也被 URL 或文件授权规则限制了查看 Support 页面的权限,那他们将会看到如下所示的导航结构。
Home Products Hardware Software Discounts Services Training Consulting
安全调整与 ASP.NET 角色协同合作。因此,在安全调整工作时的页面必须使用访问规则(allow
和 deny
元素)进行限制。
安全调整默认时是被禁用的,并且无法进行可编程控制;只能在 Web.config 文件中设置。这同样适用于任何继承自 SiteMapProvider
对象的自定义对象。
要启用安全调整,就需要在 Web.config 文件中配置一个 siteMap
元素。如果网站地图只使用默认的 ASP.NET 网站地图提供者,则 Web.config 文件不需要包含任何 siteMap
元素,在适当情况下还可以通过手动添加。下例代码添加默认网站地图提供者并启用安全调整。
<system.web> <!-- …other configuration settings --> <siteMap defaultProvider="XmlSiteMapProvider" enabled="true"> <providers> <add name="XmlSiteMapProvider" description="Default SiteMap provider." type="System.Web.XmlSiteMapProvider " siteMapFile="Web.sitemap" securityTrimmingEnabled="true" /> </providers> </siteMap> </system.web>
安全调整通过对 siteMapNode
元素的配置来使用 URL 授权检测用户是否拥有某 URL 链接访问许可。这个额外工作减少了依赖于节点的授权数量。安全调整被启用之后,可以使用下列方法来改进性能:
限制网站地图文件中的节点数量。网站地图文件中的节点数超过 150 会明显延长安全调整操作所消耗的时间。
显式设置 siteMapNode
元素的 roles
参数。注意在 roles
参数被设置成通配符或星号(*)的时候,请确保显示给任何客户端的节点内容都是安全的。roles
参数的存在允许 ASP.NET 在用户属于参数中所列角色时绕过与 siteMapNode
相关联的 URL 授权。
要避开对子网站地图节点的无意调整,请小心配置授权规则和 roles
参数。假设存在下列显示在 ASP.NET 页面中的导航结构。
Home Products Hardware
Products.aspx 文件中设置的 URL 或文件授权规则不能够拥有比 Hardware.aspx 页面中所设置的授权规则更多的限制。另外,由于父链接 Products 已经被隐藏,Hardware 链接也必须隐藏,即使用户拥有查看权限。要想暴露被隐藏的链接,请在它们的网站地图节点中同时添加 roles
参数,并赋值为被忽视的 ASP.NET 角色列表。
网站地图的根节点最好能够被所有人访问。要想这样做,请将 roles
参数设置成星号(*)或通配符,如下例代码所示。
<?xml version="1.0" encoding="utf-8" ?> <siteMap> <siteMapNode title="Home" description="Home" url="default.aspx" roles="*"> <!-- other <siteMapNode> elements --> </siteMapNode> </siteMap>
网站地图中可以引用 Web 应用程序以外的 URL。ASP.NET 无法检测对于应用程序以外的 URL 访问。因此,如果启用安全调整,对应的网站地图节点则只有在 roles
参数设置成星号(*)时才可见,从而允许所有客户端查看这些未经过访问测试的 URL 节点。
可以同时使用多个网站地图来定义同一 Web 站点中的导航结构。比如,Web.sitemap 文件可以与 Web.config 文件一样被分开存放在不同的目录。
网站地图被链接到每一个父网站地图的 siteMapFile
元素或 SiteMapNode
对象的 provider
属性中的子网站地图文件或提供者。
下例代码定义了引用其他网站地图的网站地图节点。
<?xml version="1.0" encoding="utf-8" ?> <siteMap> <!-- other <siteMapNode> elements --> <siteMapNode siteMapFile="~/Customers/Customers.sitemap" securityTrimmingEnabled="true" /> </siteMap>
使用导航控件为页面添加网站导航功能只需要编写少量代码(甚至不需要代码),但是也可以对网站导航进行可编程控制。在 Web 应用程序运行时,ASP.NET 会自动暴露一个反映网站地图结构的 SiteMap
对象,该对象的所有成员都是静态的。接着,这个 SiteMap
对象暴露一个包含地图中每个节点属性的 SiteMapNode
对象集合。原因就是,在使用时, SiteMapPath
控件会与 SiteMap
和 SiteMapNode
对象协同合作,自动呈现合适的链接内容。
可以在自定义代码中使用 SiteMap
,SiteMapNode
,以及 SiteMapProvider
对象进行网站地图结构间的跳转或创建显示网站地图数据的自定义控件。网站地图的信息不允许被写入。但是可以对实例中的网站地图节点进行修改。
ASP.NET 使用默认的网站地图提供者 XmlSitemapProvider
来读取 Web.sitemap 文件。如果想把网站地图信息保存到其他位置,可以创建自定义网站地图提供者并配置应用程序以便对自定义提供者进行调用。网站地图提供者的配置信息被保存在 Web.config 文件中。当应用程序运行时,ASP.NET 将调用能够按需要获取网站地图数据的自定义提供者。ASP.NET 会为自定义提供者返回的信息创建 SiteMapNode
对象并分配相应的系统资源。这些对象还可以使用 SiteMap
对象进行可编程访问。
安全提示:实现自定义网站地图提供者来存储非 .sitemap 扩展名的文件中的网站地图数据时潜在一个安全隐患。默认时的 ASP.NET 配置会在客户端下载之前对包含已知文件扩展名(如 .sitemap)的文件进行保护。为了保护网站数据,请把自定义的非 .sitemap 扩展名网站地图数据文件保存到 App_Data 目录。
在启用之后,安全调整会影响到 SiteMap
,SiteMapNode
,以及 SiteMapNodeCollection
对象中的部分成员的行为。在使用这些对象时,请先了解下列可能被影响到的行为:
网站导航 API 成员在对用户没有查看权限的网站地图节点进行引用时会返回空值(null
)。比如,使用 CurrentNode
,NextSibling
,ParentNode
,以及 PreviousSibling
等属性尝试获取某个被限制网站地图节点信息时均会返回空值(null
)。
如果网站导航 API 成员需要在网站地图节点树中进行跳转,那么针对于任何不允许用户查看的网站地图节点的跳转都是被禁止的。比如,当 ChildNodes
方法返回执行结果时,结果节点集合将被过滤并只包括那些允许用户查看的节点。类似的 API 成员都需要保持对节点路径的跟踪(如 Clone
方法或 IsDescendantOf
方法),且路径的内容终止于被限制节点。这样可以减少克隆操作结果中的节点数据。同时对 IsDescendantOf
方法的调用也会返回 false
值。另外,可以通过对某个节点的结构化从而使其成为被请求节点的后代。
网站导航 API 成员对于没有安全用户查看权限的根节点的引用会产生 InvalidOperationException
异常。只有根目录提供者的根节点才需要允许所有用户的访问,从而防止第一次获取 SiteMap
对象时就发生异常。
如果 SiteMapNode
对象错误地引用了其他网站地图文件或提供者时会产生 ConfigurationException
异常。
提示:网站地图中可以引用 Web 应用程序以外的 URL。ASP.NET 无法检测对于应用程序以外的 URL 访问。因此,如果启用了安全调整,此类地图节点则在参数 roles
被设置成星号(*)之前始终不可见,从而允许所有客户端能够在不需要对 URL 进行访问测试的情况下查看到链接内容。