使用 Reporting Services 中的窗体身份验证

Microsoft Corporation

适用范围:
Microsoft® SQL Server™ 2000 Reporting Services

**摘要:**了解有关 Reporting Services 安全扩展方面的知识,着重学习窗体身份验证。此外,下载和部署 Reporting Services 的窗体身份验证扩展示例。

要安装示例代码,请下载 Forms Authentication Sample installer,并在计算机上运行它。

本页内容

引言 引言
关于本指南 关于本指南
Reporting Services 平台 Reporting Services 平台
窗体身份验证示例 窗体身份验证示例
结论 结论
参考资料 参考资料

引言

部署安全的分布式企业报告解决方案是一个极具挑战性的过程。从报告访问到提供重要数据(有时是敏感数据)的数据源,您需要针对如何在报告环境中对用户进行安全的身份验证和授权作出决策。在安全方面,报告是报告链中最薄弱的环节。

所需的安全类型取决于报告环境和已安装的安全系统类型。Microsoft® Windows® Authentication 是用于确保 Microsoft® SQL Server™ 2000 Reporting Services 中的报告安全性的主要系统。Windows Authentication 提供与其他 Microsoft 服务器产品的紧密集成,由于 Reporting Services 是在 Windows Authentication 上设计和测试的,因此它在这个环境中的安全性最高。

然而,在某些情况下,可能需要对 Reporting Services 安全系统进行扩展,以满足企业自定义安全的需要。您可以通过功能丰富的 Reporting Services API 开发平台达到这一目的。本指南将概述 Reporting Services 中的扩展,尤其是安全扩展。您还可以下载适用于 Reporting Services 的示例窗体身份验证扩展,并对它进行深入研究。随后,您可以利用 Reporting Services 安全扩展将自定义安全添加到企业报告解决方案中。

关于本指南

本指南中提供的信息旨在:

  • 向您介绍 Reporting Services 安全扩展。

  • 确定在 Reporting Services 中使用自定义身份验证和授权的位置和方式。

  • 介绍身份验证和授权在 Reporting Services 中的工作方式。

  • 介绍窗体身份验证及其实现方式。

  • 为您提供了一个可以下载和研究的窗体身份验证示例。

必备知识

本指南未介绍 ASP.NET 安全或窗体身份验证,未提供有关编程或应用程序安全的深层次知识。作为一名期望为 Reporting Services 实现安全扩展的开发人员,您应该对以下一个或多个方面有着深入的了解:

  • Microsoft Reporting Services 功能,尤其是身份验证、授权和基于角色的安全。

  • Microsoft .NET Framework。

  • ASP.NET 和 ASP.NET 安全。

  • 窗体身份验证。

  • .NET 语言方面的开发经历。本文仅提供用 C# 编写的示例。

要直接了解代码,可以转到“窗体身份验证示例”部分。不过,您可能会发现前面的几部分很有帮助,这些部分介绍了您将使用的某些技术以及如何将这些技术组合在一起使用。

Reporting Services 平台

通过 Reporting Services,可在整个企业中设计、部署和交付报告。从开发人员的角度来看,Reporting Services 通过 .NET Framework 和 Web service 的关键开发平台提供了各种编程机会。Reporting Services 可以通过“随手可用”的方式进行部署,从而可以在任何公司中提供全面的报告解决方案。然而,Reporting Services 的开放式和可扩展编程体系结构使它已不再是一个现成的产品,而更像是开发人员以及最终用户的报告平台。

扩展 Reporting Services

Reporting Services 具有可扩展性。通过托管代码 API,可以开发、安装和管理许多 Reporting Services 组件使用的扩展。可以使用 .NET Framework 创建专用或共享的程序集,并添加新的 Reporting Services 功能以满足日益增长的业务需求。开发人员可通过以下方式扩展 Reporting Services:

  • 除了 Reporting Services 当前附带的 Microsoft SQL Server、Oracle 和 OLE DB 提供程序以外,创建其他数据处理扩展。数据处理扩展可用于从您自己特有的数据源中读取数据,并可用于在创建和筛选数据集时并入其他业务逻辑。

  • 除了 Reporting Services 当前附带的电子邮件和文件共享交付扩展以外,创建其他交付扩展。交付扩展可用于向传真机、寻呼机、打印机等设备交付报告。

  • 除 Reporting Services 已经附带的呈现扩展之外,创建其他呈现扩展。

  • 除了 Windows Authentication 扩展(它当前是该产品的默认安全机制)之外,创建其他安全扩展。

如前所述,本指南主要介绍了如何通过窗体身份验证扩展 Reporting Services 的安全系统。

安全扩展

通过 Reporting Services 安全扩展,可以对用户或组进行身份验证和授权,即它使不同的用户能够登录到报告服务器,并根据他们的身份执行不同的任务或操作。默认情况下,Reporting Services 使用基于 Windows 的身份验证扩展,该身份验证扩展使用 Windows 帐户协议验证声称拥有该系统帐户的用户的身份。Reporting Services 使用基于角色的安全系统对用户进行授权。Reporting Services 基于角色的安全模式类似于其他技术的基于角色的安全模式。由于安全扩展基于开放式、可扩展的 API,因此可以在 Reporting Services 中创建新身份验证和授权扩展。以下是使用基于窗体的身份验证和授权的安全扩展实现的典型示例:

ufairs01

1如图所示,身份验证和授权按如下过程进行:

  1. 用户尝试通过输入 URL 来访问 Report Manager,然后被重定向到一个为客户端应用程序收集用户凭据的窗体。

  2. 该用户将凭据提交给窗体。

  3. 通过 LogonUser 方法将该用户的凭据提交给 Reporting Services Web service。

  4. Web service 调用客户提供的安全扩展,并验证自定义安全机构中是否存在该用户名和密码。

  5. 进行身份验证时,Web service 将创建身份验证票据(称作“Cookie”),管理该票据,并验证该用户的角色能否访问 Report Manager 的主页。

  6. Web service 将 Cookie 返回给浏览器,并在 Report Manager 中显示相应的用户界面。

  7. 身份验证结束后,浏览器向 Report Manager 发出请求,同时在 HTTP 标头中传输此 Cookie。这些请求是为响应 Report Manager 应用程序中的用户操作而发出的。

  8. 该 Cookie 连同请求的用户操作在 HTTP 标头中一起被传输到 Web service。

  9. Cookie 将接受验证,如果它有效,报告服务器将从报告服务器数据库中返回与请求操作相关的安全描述符和其他信息。

  10. 如果 Cookie 有效,报告服务器将调用安全扩展,以检查该用户是否有权执行特定的操作。

  11. 如果该用户已被授权,报告服务器将执行请求的操作,并将控制返回给调用方。

  12. 该用户经过身份验证后,对报告服务器的 URL 访问将使用相同的 Cookie。该 Cookie 在 HTTP 标头中传输。

  13. 用户继续在报告服务器上请求操作,直至会话结束。

何时实现安全扩展

Microsoft 建议您尽可能地使用 Windows Authentication。不过,但在以下两种情况下,应使用 Reporting Services 的自定义身份验证和授权:

  • Internet 或 Extranet 应用程序未使用或无法使用 Windows 帐户。

  • 您具有自定义的用户和角色,并且需要在 Reporting Services 中提供匹配的授权方案。

安全扩展 API

下表列出了安全扩展的可用接口和类。

接口或类

说明

IAuthenticationExtension 接口

表示 Reporting Services 中的身份验证扩展,使您能够实现可用于用户身份验证(使用自定义身份验证方案)的安全扩展类。

IAuthorizationExtension 接口

表示可用于扩展 Reporting Services 的授权功能的扩展,使您能够实现可用于授权用户执行操作的安全扩展类。

IExtension 接口

表示 Reporting Services 中的扩展。

AceCollection 类

表示指定一个或多个受信任者的访问权限的访问控制项的集合。

AceStruct 类

受信任者(用户、组或计算机)的访问控制项,用于指定受信者可以对报告服务器数据库中的项目执行的操作。

CatalogOperationsCollection 类

表示目录操作集合。

DatasourceOperationsCollection 类

表示数据源操作集合。

FolderOperationsCollection 类

表示文件夹操作集合。

OperationNames 类

包含用户可以对 Reporting Services 中的项目执行的操作的字段名和相应值。

ReportOperationsCollection 类

表示报告操作集合。

ResourceOperationsCollection 类

表示资源操作集合。

有关安全扩展 API 的各种接口和类的详细信息,请参阅 Reporting Services 联机丛书。

Reporting Services 中的身份验证

身份验证是建立用户身份权限的过程。有许多方法可用于用户身份验证。最常用的方法是使用密码。实现窗体身份验证时,应使用这样的实现:请求用户提供凭据(一般通过要求输入登录名和密码的某种界面),然后根据用户存储(例如,数据库表或配置文件)验证用户。如果凭据无法得到验证,身份验证进程将失败,用户将获取匿名身份。

在 Reporting Services 中,Windows 操作系统通过集成的安全性或通过用户凭据的显式接收和验证来处理用户的身份验证。可对 Reporting Services 中的自定义身份验证进行开发,使之支持其他身份验证方案。为此,可使用安全扩展接口 IAuthenticationExtension。所有扩展都继承于 IExtension,它是报告服务器部署和使用的任何扩展的基本接口。IExtensionIAuthenticationExtensionMicrosoft.ReportingServices.Interfaces 命名空间的成员。

LogonUser 方法是 Reporting Services 中所有身份验证的核心。可使用它将用户凭据传递给报告服务器进行验证。基础安全扩展实现包含自定义身份验证代码的 IAuthenticationExtension.LogonUser。在窗体身份验证示例(将在本指南后面部分介绍)中,LogonUser 根据提供的凭据和数据库中的自定义用户存储区执行身份验证检查。在窗体身份验证示例中,它类似于以下过程:

AuthenticationExtension.cs (窗体身份验证示例)中

public bool LogonUser(string userName, string password, string authority)
{
   return AuthenticationUtilities.VerifyPassword(userName, password);
}

AuthenticationUtilities.cs (窗体身份验证示例)中

internal static bool VerifyPassword(string suppliedUserName,
   string suppliedPassword)
{ 
   bool passwordMatch = false;
   // 基于用户名从数据库中获取 Salt 和密码。
   // 请参阅“How To:Use DPAPI (Machine Store) from ASP.NET”、“How To:
   // Use DPAPI (User Store) from Enterprise Services”和“How To:
   // Create a DPAPI Library”,以了解有关如何使用
   // DPAPI 安全地存储连接字符串的详细信息。
   SqlConnection conn = new SqlConnection(
      "Server=localhost;" + 
      "Integrated Security=SSPI;" +
      "database=UserAccounts");
   SqlCommand cmd = new SqlCommand("LookupUser", conn);
   cmd.CommandType = CommandType.StoredProcedure;

   SqlParameter sqlParam = cmd.Parameters.Add("@userName",
       SqlDbType.VarChar,
       255);
   sqlParam.Value = suppliedUserName;
   try
   {
      conn.Open();
      SqlDataReader reader = cmd.ExecuteReader();
      reader.Read(); // 跳转到唯一行
      // 从返回的数据流返回输出参数
      string dbPasswordHash = reader.GetString(0);
      string salt = reader.GetString(1);
      reader.Close();
      // 现在采用用户输入的 Salt 和密码
      // 并将它们串联在一起。
      string passwordAndSalt = String.Concat(suppliedPassword, salt);
      // 现在对它们进行哈希操作
      string hashedPasswordAndSalt =
         FormsAuthentication.HashPasswordForStoringInConfigFile(
         passwordAndSalt,
         "SHA1");
      // 现在验证它们。如果它们相等,则返回 true
      passwordMatch = hashedPasswordAndSalt.Equals(dbPasswordHash);
   }
   catch (Exception ex)
   {
       throw new Exception("Exception verifying password. " +
          ex.Message);
   }
   finally
   {
       conn.Close();
   }
   return passwordMatch;
}

身份验证流程

Reporting Services Web service 提供自定义身份验证,以便 Report Manager 和报告服务器能够进行窗体身份验证。

Reporting Services Web service 的 LogonUser 方法用于将凭据提交给报告服务器,以进行身份验证。Web service 使用 HTTP 标头将身份验证票据(称为“Cookie”)从服务器传递到客户端,以响应已验证的登录请求。

下图描述了当使用配置为使用自定义身份验证扩展的报告服务器来部署您的应用程序时,对要访问 Web service 的用户进行身份验证的方法。

ufairs02

2如图 2 所示,身份验证进程如下:

  1. 客户端应用程序调用 Web service 方法 LogonUser 对用户进行身份验证。

  2. Web service 调用安全扩展(具体而言,是指实现 IAuthenticationExtension 的类)的 LogonUser 方法。

  3. LogonUser 的实现验证用户存储或安全机构中的用户名和密码。

  4. 身份验证成功后,Web service 将创建 Cookie 并针对会话对其进行管理。

  5. Web service 通过 HTTP 标头将身份验证票据返回给调用的应用程序。

Web service 通过安全扩展成功对用户进行身份验证后,将生成一个 Cookie,用于随后的请求。由于报告服务器没有安全机构,因此该 Cookie 不会一直保存在自定义安全机构中。Cookie 从 Web service 方法 LogonUser 返回,并用于随后的 Web service 方法调用以及 URL 访问。

**安全:**为了避免在传输过程中泄露 Cookie,应使用安全套接字层 (SSL) 加密安全地传输从 LogonUser 返回的 Cookie。

如果在安装了自定义安全扩展的情况下通过 URL 访问来访问报告服务器,则 Internet 信息服务 (IIS) 和 ASP.NET 将自动管理身份验证票据的传输。如果通过 SOAP API 访问报告服务器,则代理类的实现必须包含对身份验证票据管理的附加支持。有关使用 SOAP API 和管理身份验证票据的详细信息,请参阅本指南后面的“将 Web service 用于自定义安全”。

Reporting Services 中的身份验证

授权是指决定是否为某一身份授予请求类型的访问权限(访问报告服务器数据库中的给定资源的权限)的过程。Reporting Services 使用基于角色的授权体系结构,即,基于应用程序中的用户角色授予用户访问给定资源的权限。Reporting Services 的安全扩展包含授权组件(一旦用户在报告服务器上得到验证,该授权组件便用于授予用户权限)的实现。当用户试图通过 SOAP API 和通过 URL 访问对系统或报告服务器项目执行操作时,授权便被调用。为此,可以使用安全扩展接口 IAuthorizationExtension。如前所述,所有扩展都继承于 IExtension,它是部署的任何扩展的基本接口。IExtensionIAuthorizationExtensionMicrosoft.ReportingServices.Interfaces 命名空间的成员。

在授权中,任何自定义安全实现的关键是访问权检查,该检查在方法 CheckAccess 中进行。每当用户试图在报告服务器上进行操作时,CheckAccess 便会被调用。CheckAccess 方法将针对每种操作类型进行重载。对于文件夹操作,访问权检查的示例可能如下所示:

// 针对文件夹操作重载
public bool CheckAccess(
   string userName, 
   IntPtr userToken, 
   byte[] secDesc, 
   FolderOperation requiredOperation)
{
   // 如果用户是管理员,则允许无限制访问。
   if (userName == m_adminUserName) 
      return true;

   AceCollection acl = DeserializeAcl(secDesc);
   foreach(AceStruct ace in acl)
   {
         if (userName == ace.PrincipalName)
         {
            foreach(FolderOperation aclOperation in 
               ace.FolderOperations)
            {
               if (aclOperation == requiredOperation)
                     return true;
            }
         }
   }
   return false;
}

报告服务器通过传入登录用户的名称、用户令牌、操作项目的安全描述符和请求的操作来调用 CheckAccess 方法。此处。您将检查用户名的安全描述符和完成请求的适当权限,然后返回 true,表明访问权限已授予,或者返回 false,表明访问权限被拒绝。

安全描述符

为报告服务器数据库中的项目设置授权策略时,客户端应用程序(例如 Report Manager)将把用户信息以及项目的安全策略提交给安全扩展。此安全策略和用户信息统称为安全描述符。安全描述符包含报告服务器数据库中的项目的以下信息:

  • 对项目具有某种操作权限的组或用户。

  • 项目的类型。

  • 控制项目访问权的随机访问控制列表。

安全描述符是通过 Web service 方法 SetPoliciesSetSystemPolicies 创建的。有关这些方法和 Web service 的详细信息,请参阅 Reporting Services 联机丛书。

授权流程

Reporting Services 授权由当前在配置为在服务器上运行的安全扩展控制。授权是基于角色的,并受限于 Reporting Services 安全体系结构提供的权限和操作。下图说明了如何授权用户对报告服务器数据库中的项目执行操作。

ufairs03

3如图 3 所示,授权按照以下顺序进行:

  1. 身份验证完成后,客户端应用程序通过 Reporting Services Web service 方法向报告服务器发出请求。身份验证票据以每个 Web 请求的 HTTP 标题中的 Cookie 的形式传递给报告服务器。

  2. 在进行任何访问权检查之前,Cookie 将被验证。

  3. 完成 Cookie 的验证后,报告服务器将调用 GetUserInfo,以便向用户授予标识。

  4. 用户通过 Reporting Services Web service 尝试操作。

  5. 报告服务器调用 CheckAccess 方法,

  6. 并随即检索安全描述符,并将其传递给 CheckAccess 的自定义安全扩展实现。此时,用户、组或计算机将与访问的项目的安全描述符进行比较,并被授予执行请求操作的权限。

  7. 如果用户得到授权,Web service 将执行操作,并向调用应用程序返回响应。

窗体身份验证示例

如果您尚未安装窗体身份验证示例,请下载 Forms Authentication Sample installer,并在计算机上运行它,以安装示例代码。

关于该示例

窗体身份验证示例安全扩展可作为本指南的一部分下载,它使用窗体身份验证以及 SQL Server 提供与 Reporting Services 一起使用的自定义安全模式。本示例仅用于演示目的,而不适用于生产环境,也未在生产环境中进行测试。Microsoft 对此示例不提供技术支持。在某些情况下,该示例中演示了最佳做法(例如,创建单向哈希、带salt 的密码)。在其他情况下,为简单起见,而回避了最佳做法。应注意,该示例安全扩展的设置和管理经常要求您在报告服务器计算机上拥有管理员访问权。不管怎样,都不建议在连接环境中的生产服务器上使用该示例。

如果您对 Reporting Services 安全扩展有任何疑问,请与 Microsoft 咨询服务 (MCS)、主要支持服务 (PSS) 或其他 Microsoft 支持服务代表联系。

要求

要使用本示例,必须安装了以下工具:

  • 安装了 Microsoft SQL Server 2000 Reporting Services 的报告服务器。

  • 用于访问 Report Manager 的 Microsoft Internet Explorer 6.0 或更高版本。

  • 安装了 Microsoft® Visual Studio® .NET 2003 的开发计算机。

注意事项

实现自定义安全扩展或使用该示例时,请注意以下事项:

  • 不能在混和模式安全系统(例如,同时使用 Windows Authentication 和窗体身份验证)下运行报告服务器。这也适用于任何 ASP.NET 应用程序。

  • 务必保存因配置该示例而更改的所有配置文件的备份副本。

  • 尽管可以在部署该示例后恢复到 Windows Authentication,但这可能有一定难度。有关详细信息,请参阅本指南后面的“删除示例扩展”。

  • 覆盖 Windows Authentication 是非常危险的。报告服务器在安全方面具有可扩展性,但仅使用了 Windows Authentication 对它进行了全面测试和支持。

  • 请始终将安全套接字层 (SSL) 用于窗体身份验证。

  • 在本示例中,用户输入传递到 Transact-SQL 命令,以进行身份验证。在您自己的自定义安全扩展(将窗体身份验证和 SQL Server 配合使用)中,应谨慎对待用户输入验证,并确保结果命令不包含语法错误。应确保验证所有用户输入,以防恶意用户导致应用程序运行任意的 SQL 命令(也称为“SQL 插入攻击”)。登录进程中验证提供的用户名尤为重要,因为报告服务器自定义安全模式完全取决于能否对用户进行正确的标识、身份验证和授权。

  • 在自定义用户存储中,避免用户输入带有以下字符的名称:: ? ; @ & = + $ , \ * > < | . " /。带有这些字符的用户名可能会导致“My Reports”(我的报告)功能出现问题,因为文件夹在服务器中是使用用户名创建的,且这些字符可能导致文件夹名称和文件夹路径出现问题。示例代码使用正则表达式测试用户名是否有效,并确保路径名不超过允许的最大路径长度。应该在自定义身份验证代码中执行类似的验证。

窗体身份验证

窗体身份验证是一种 ASP.NET 身份验证,通过这种身份验证,可将未经身份验证的用户定向到 HTML 窗体。当用户提供凭据后,系统将发出包含身份验证票据的 Cookie。在随后的请求中,系统首先检查该 Cookie,确定报告服务器是否已对用户进行身份验证。

Reporting Services 本身不支持窗体身份验证。不过,可使用 Reporting Services API 提供的安全扩展接口对 Reporting Services 进行扩展,使其支持窗体身份验证。如果将 Reporting Services 扩展为可以使用窗体,请将安全套接字层 (SSL) 用于所有与报告服务器进行的通信,以防恶意用户获取对其他用户的 Cookie 的访问权。SSL 可使客户端和报告服务器相互进行身份验证,并确保其他计算机无法读取这两台计算机之间的通信内容。通过 SSL 连接从客户端发出的所有数据都经过加密,这样,恶意的用户便无法截获发送至报告服务器的密码或数据。

实现窗体身份验证通常是为了支持非 Windows 帐户和身份验证。图形界面将展示给请求访问报告服务器的用户,提供的凭据将提交给安全机构,以进行身份验证。

当有交互式用户输入凭据时,窗体身份验证方案就会派上用场。不过,对于与 Reporting Services Web service 直接通信的无人值守应用程序,必须将窗体身份验证与自定义身份验证方案组合使用。

以下情况下,窗体身份验证适用于 Reporting Services:

  • 需要对没有 Microsoft Windows 帐户的用户进行存储和身份验证,并

  • 需要在 Web 站点的不同页面间提供您自己的用户界面窗体作为登录页面。

编写支持窗体身份验证的自定义安全扩展时,请考虑以下事项:

  • 如果使用窗体身份验证,则必须在 Internet 信息服务 (IIS) 中的报告服务器虚拟目录上启用匿名访问。

  • 必须将 ASP.NET 身份验证设置为“Forms”(窗体)。可以在报告服务器的 Web.config 文件中配置 ASP.NET 身份验证。

  • Reporting Services 可使用 Windows Authentication 或自定义身份验证对用户进行身份验证和授权。Reporting Services 不支持同时使用多个安全扩展。

部署示例

要运行和检查窗体身份验证示例的代码,必须先执行几个步骤。执行安装和配置步骤后,即可在报告服务器上使用或调试示例,或在 Visual Studio .NET 中查看示例代码。

编译和安装扩展程序集

必须按照以下步骤编译和安装扩展。这些步骤假设您已将 Reporting Services 安装到默认位置:C:\Program Files\Microsoft SQL Server\MSSQL\Reporting Services。该位置在本指南的余下部分统称为 <install>

使用 Visual Studio .NET 编译示例

  1. 在 Microsoft Visual Studio .NET 2003 中打开 CustomSecurity.sln。如果已经下载了源代码并将示例安装到默认位置,便可以在 C:\Program Files\Microsoft SQL Server\MSSQL\Reporting Services\Samples\Extensions 中访问到它。

  2. 在“解决方案资源管理器”中,选择 CustomSecurity 项目。

  3. 在“项目”菜单上,单击“添加引用”。

  4. “添加引用”对话框将打开。

  5. 单击“.NET”选项卡。

  6. 单击“浏览”进行导航,以在本地驱动器上找到 Microsoft.ReportingServices.Interfaces。默认情况下,该程序集位于 <install>\ReportServer\bin 目录中。单击“确定”。

    选定的引用被添加至项目中。

  7. 在“生成”菜单中单击“生成解决方案”。

  8. 将 Microsoft.Samples.ReportingServices.CustomSecurity.dll 和 Microsoft.Samples.ReportingServices.CustomSecurity.pdb 复制到 <install>\ReportServer\bin 目录中。

  9. 将 Microsoft.Samples.ReportingServices.CustomSecurity.dll 和 Microsoft.Samples.ReportingServices.CustomSecurity.pdb 复制到 <install>\ReportManager\bin 目录中。

  10. 将 Logon.aspx 页复制到 <install>\ReportServer 目录中,并将 UILogon.aspx 页复制到 <install>\ReportManager\Pages 目录中。

将该扩展添加到配置文件中。

将程序集和登录页体身份验证适用于 Report,需要对 Report Server 和 Report Manager 配置文件做一些修改。

要点: 在进行任何更改前,请备份所有配置文件。

修改 RSReportServer.config 文件

  1. 使用 Visual Studio .NET 或一个简单的文本编辑器(例如,记事本)打开 RSReportServer.config 文件。RSReportServer.config 位于 <install>\ReportServer 目录中。

  2. 找到 <Security> 和 <Authentication> 元素,并按如下方式修改设置:

    <Security>
    

<Extension Name="Forms" Type="Microsoft.Samples.ReportingServices.CustomSecurity.Authorization, Microsoft.Samples.ReportingServices.CustomSecurity" > <Configuration> <AdminConfiguration> <UserName>username</UserName> </AdminConfiguration> </Configuration> </Extension> </Security> <Authentication> <Extension Name="Forms" Type="Microsoft.Samples.ReportingServices.CustomSecurity.AuthenticationExtension, Microsoft.Samples.ReportingServices.CustomSecurity" /> </Authentication>

修改 RSWebApplication.config 文件

  1. 然后,需要打开位于 <install>\ReportManager 目录中的 Report Manager 配置文件 RSWebApplication.config。

  2. 找到 <UI> 元素,并按如下方式更新它:

    <UI>
    

<CustomAuthenticationUI> <loginUrl>/Pages/UILogon.aspx</loginUrl> <UseSSL>True</UseSSL> </CustomAuthenticationUI> <ReportServerUrl>http://<server>/ReportServer</ReportServerUrl> </UI>

**安全:** 如果在未安装 SSL 证书的开发环境中运行示例扩展,则必须在上一个配置项中将 **\<UseSSL\>** 元素的值更改为 False。将 Reporting Services 和窗体身份验证组合使用时,Microsoft 建议您始终使用 SSL。

添加扩展的安全策略

您将需要为自定义安全扩展添加代码组,以便向扩展授予 FullTrust 权限。为此,可以将代码组添加到 <install>\ReportServer 目录中的 rssrvpolicy.config 文件中。在安全策略文件中找到具有 $CodeGen 的 URL 成员身份的现有代码组(如下所示),然后按如下方式将项目添加到 rssrvpolicy.config 中。

<CodeGroup
   class="UnionCodeGroup"
   version="1"
   PermissionSetName="FullTrust">
   <IMembershipCondition 
      class="UrlMembershipCondition"
      version="1"
      Url="$CodeGen$/*"
   />
</CodeGroup>
<CodeGroup
   class="UnionCodeGroup"
   version="1"
   Name="SecurityExtensionCodeGroup"
   Description="示例安全扩展的代码组"
   PermissionSetName="FullTrust">
   <IMembershipCondition 
      class="UrlMembershipCondition"
      version="1"
      Url="C:\Program Files\Microsoft SQL Server\MSSQL\Reporting Services\ReportServer\bin\Microsoft.Samples.ReportingServices.CustomSecurity.dll"
   />
</CodeGroup>

**注意:**为简单起见,窗体身份验证示例命名不是很严格,在安全策略文件中要求的 URL 成员身份项也很简单。在生产安全扩展实现中,应该创建强名称程序集,并在添加程序集的安全策略时使用强名称成员身份条件。有关强名称程序集的详细信息,请参阅 MSDN 上的“Creating and Using Strong-Named Assemblies”,其网址为 http://msdn.microsoft.com/library/en-us/cpguide/html/cpconworkingwithstrongly-namedassemblies.asp(英文)。

然后,需要在 <install>\ReportManager 目录中的 Report Manager 策略文件中为 MyComputer 代码组增加权限。在 rsmgrpolicy.config 中找到以下代码组,并按如下方式将 PermissionSetName 属性从 Execution 更改为 FullTrust

<CodeGroup 
        class="FirstMatchCodeGroup" 
        version="1" 
        PermissionSetName="FullTrust"
        Description="该代码组为 MyComputer 代码授予 Execution 
权限。 ">
    <IMembershipCondition 
            class="ZoneMembershipCondition"
            version="1"
            Zone="MyComputer" />

配置 Web.config 文件

要使用窗体身份验证,您需要修改 Report Manager 和 Report Server 的 Web.config 文件,以更改身份验证并禁用模拟。

修改 Report Server Web.config 文件

  1. 在文本编辑器中打开 Web.config 文件。默认情况下,该文件位于 <install>\ReportServer 目录中。

  2. 找到 <identity> 元素,并将 impersonate 属性设置为 false

    <identity impersonate="false" />
    
  1. 找到 <authentication> 元素,并将 mode 属性更改为 Forms

  2. 将以下 <forms> 元素作为 <authentication> 元素的子级添加,并按如下方式设置 loginUrlnametimeoutpath 属性:

    <authentication mode="Forms">
    

<forms loginUrl="logon.aspx" name="sqlAuthCookie" timeout="60" path="/"></forms> </authentication>

  1. 将以下 <authorization> 元素直接添加到 <authentication> 元素之后。

    <authorization> 
    

<deny users="?" /> </authorization>

这会拒绝将访问报告服务器的权限授予未经身份验证的用户。\<**authentication**\> 元素的先前建立的 **loginUrl** 属性将把未经身份验证的用户重定向到 Logon.aspx 页上。

修改 Report Manager Web.config 文件

  1. 打开 Report Manager 的 Web.config。它位于 <install>\ReportManager 目录中。

  2. 找到 <identity impersonate= "true" /> 部分,然后按如下方式更改它,以便禁用模拟:<identity impersonate="false" />。

配置匿名身份验证

默认情况下,Windows 用户组 Guests 包含 IUSR_computername 帐户。该帐户用于最初的本地登录以及查看 Logon.aspx 页。要支持窗体身份验证,必须启用 ReportServer 虚拟目录的匿名访问。默认情况下,匿名访问被禁用。

启用匿名身份验证

  1. 在“Internet 信息服务”中,选择 ReportServer 虚拟目录(通常是默认网站的成员),然后打开它的属性选项卡。

  2. 单击“目录安全性”选项卡。

  3. 在“匿名访问和身份验证控制”部分,单击“编辑”。

    将显示“身份验证方法”对话框。

  4. 选中“匿名访问”复选框。

  5. 单击“确定”。

  6. 对 Reports 虚拟目录重复上述步骤。

创建用户帐户数据库

示例包含一个数据库脚本,即 createuserstore.sql,用于在 SQL Server 数据库中为窗体示例建立一个用户存储。

创建 UserAccounts 数据库

  1. 打开“查询分析器”,然后连接到 SQL Server 的本地实例。

  2. 找到 SQL 脚本文件 createuserstore.sql。该脚本文件包含在示例项目文件中。注意,在脚本的结尾处,必须用您自己的计算机名替换“LocalMachine”。对于 Windows 2003 用户,用 NT AUTHORITY\NETWORK SERVICE 替换 LocalMachine\ASPNET(在 IIS 5 兼容模式下时除外)

  3. 运行查询以创建 UserAccounts 数据库。

  4. 退出“查询分析器”。

测试示例

通过以下步骤测试示例扩展。注册管理员用户,即将该用户名、密码哈西和 Salt 值添加到 UserAccounts 数据库中的用户表。它还将要求您在报告服务器配置文件中输入该用户名。然后,您将以同一个用户身份登录以确保报告服务器正确运行密码验证例程以及正确加载扩展程序集。

测试示例安全扩展部署

  1. 在命令提示符下运行 iisreset.exe,重新启动 IIS。

  2. 打开 Report Manager。您可以从 Reporting Services 程序菜单打开它或通过从浏览器访问 Reports 虚拟目录来打开它。

  3. 输入用户名和密码,然后单击“注册用户”,将用户添加到帐户数据库中。

  4. 打开 RSReportServer.config 文件。找到 <Security> 元素,然后按如下方式添加以前注册的用户名:

    <Security>
    

<Extension Name="Forms" Type="Microsoft.Samples.ReportingServices.CustomSecurity.Authorization, Microsoft.Samples.ReportingServices.CustomSecurity" > <Configuration> <AdminConfiguration> <UserName>username</UserName> </AdminConfiguration> </Configuration> </Extension> </Security>

  1. 返回到 UILogon.aspx 页,重新输入用户名和密码,然后单击“登录”。

您应该能够不受限制地访问 Report Manager 和报告服务器。创建的管理员用户对报告服务器的权限与对本地计算机上的内置管理员帐户的权限相同。在本示例中,只能将一位用户指定为管理员。拥有内置管理员帐户后,即可注册其他用户,并指派他们在报告服务器中的角色。

注意: 建议将管理员用户添加到报告服务器的正式 System Administrator 和 Content Manager(根文件夹)角色中。这可防止报告服务器数据库中出现空的安全描述符。有关 System Administrator 和 Content Manager 角色的详细信息,请参阅 Reporting Services 联机丛书。

将 Web Service 用于自定义安全

您可以将 Web service API 用于窗体身份验证,就像将 Windows Authentication 用于窗体身份验证一样。不过,您必须调用 Web service 代码中的 LogonUser,并传递当前用户的凭据。此外,Web service 客户端将不具备 Internet Explorer 或其他 Web 浏览器提供的自动 Cookie 管理功能。您必须扩展 ReportingService 代理类以包含 Cookie 管理。为此,可以覆盖 Web service 类的 GetWebRequestGetWebResponse 方法。

有关这方面的示例,请参阅 MSDN 上的“ReportingService.LogonUser Method”,其网址为 http://msdn.microsoft.com/library/en-us/rsprog/htm/rsp_ref_soapapi_service_lz_3d7q.asp(英文)。

调试示例扩展

在调试程序中运行示例扩展不仅可帮助您解决疑难问题,而且使您能够有效地浏览代码并查看运行中的报告服务器身份验证和授权进程。

Microsoft .NET Framework 提供了多个可帮助您分析示例代码的调试工具。工具的使用效果取决于您试图完成的任务。在本指南中,所选的调试工具是 Visual Studio .NET 2003。

调试窗体身份验证示例代码

  1. 确保按照以下步骤部署示例。

  2. 启动 Visual Studio .NET 2003,并打开测试报告服务器上的 CustomSecurity.sln。

  3. 打开 Internet Explorer,并导航至 Report Manager,同时使示例代码在 Visual Studio 中保持打开状态。

  4. 导航至 Visual Studio 和自定义安全扩展项目,并在代码中设置一些断点。

  5. 当扩展项目仍为活动窗口时,单击“调试”菜单上的“进程”。

    “进程”对话框将打开。

  6. 从进程列表中,选择 aspnet_wp.exe 进程(如果您的应用程序部署在 IIS 6.0 上,请选择 w3wp.exe),然后单击“附加”。当“附加到进程”对话框打开时,确保选择了程序类型“公共语言运行库”,然后单击“确定”。为提高调试性能,确保未选择程序类型“本机”。

  7. 现在,请在登录窗体中输入用户凭据,然后单击“登录”。如果遇到对应于断点的代码,调试程序将在第一个断点处停止执行。

  8. 使用 F11 键浏览代码。有关使用 Visual Studio 进行调试的详细信息,请参阅 Visual Studio .NET 文档。

    注意: 以这种方式进行调试需要大量的资源和处理器时间。如果遇到问题,请关闭 Visual Studio,重置 IIS,然后通过将 CustomSecurity 解决方案附加到 ASP.NET 工作进程并登录到 Report Manager 来重新开始。

删除示例扩展

尽管通常不建议这么做,但删除示例后,仍可以恢复到 Windows Authentication。要恢复到 Windows 安全,请执行下列操作:

  • 从备份副本还原下列文件:Web.config、RSReportServer.config 和 RSWebApplication.config。这将把报告服务器的身份验证和授权方法设置为默认的 Windows 安全。这还将删除您在 Report Server 或 Report Manager 配置文件中为扩展输入的内容。

  • 在 Internet 信息服务器 (IIS) 中禁用报告服务器虚拟目录的匿名访问。

删除配置信息后,安全扩展对于报告服务器将不可用。您不必删除在示例安全扩展下运行报告服务器时所创建的任何安全描述符。启用 Windows Authentication 时,报告服务器自动将 System Administrator 角色分配给托管报告服务器的计算机上的 BUILTIN\Administrators 组。不过,您必须为 Windows 用户重新手动应用任何基于角色的安全。

通常,在迁移到不同的安全扩展后,建议您不要恢复到 Windows Authentication。否则,当您试图访问报告服务器中的项目时,如果它们具有自定义安全描述符而不具有 Windows Authentication 安全描述符,则可能会遇到错误。

结论

Microsoft SQL Server 2000 Reporting Services 是一个可用于企业报告开发和部署的可扩展报告平台。Reporting Services 包含一个 Windows Authentication 模块,该模块使用 Windows 帐户确保对报告服务器访问的安全,但在某些情况下,可能需要支持不同安全模块。为此,Reporting Services 中包含了一组支持创建自定义安全扩展的安全扩展 API。在所提供的示例中,您已了解了通过窗体身份验证实现自定义安全的方法。Microsoft 正致力于通过在 Reporting Services 的当前版本和后续版本中提供安全扩展性,来满足企业中不断增长的安全需求。 作为开发者,您应该意识到实现自定义安全扩展的风险,并应该谨慎考虑报告服务器所用的安全系统是否得到正确实现和应用。

参考资料

有关详细信息,请参阅 MSDN 上的以下资源:

版本所有

本文档中包含的信息代表 Microsoft Corporation 在发布时对所讨论问题的最新观点。由于 Microsoft 必须适应不断变化的市场情况,因此,这些信息并非 Microsoft 方面所作的承诺,Microsoft 也不能保证出版日之后提供的任何信息都完全正确。

本白皮书仅供参考。MICROSOFT 对本文档中的有关信息不作任何明示或暗示的担保。

用户有责任遵从所有适用的版权法。除了版权法所赋予的权利以外,未经 Microsoft Corporation 明确书面许可,不得擅自将本文档的任何部分进行复制、存储或输入可检索系统,或以任何形式或方式(电子、机械、影印、录制或其他方式)进行传播,或用作其他目的。

Microsoft 对本文档中的主题持有专利权、专利申请权、商标权、版权或其他相关的知识产权。Microsoft 只提供在任何书面许可协议中明确规定的权利,而不授予您本文档的上述专利权、商标权、版权或其他知识产权。

©2004 Microsoft Corporation 版权所有。保留所有权利。

Microsoft、Visual Studio 和 Windows 是 Microsoft Corporation 在美国和/或其他国家的注册商标。

此处提到的真实的公司和产品名称是其各自所有者的商标。

© 2004 Microsoft Corporation 版权所有。保留所有权利。使用规定。