在应用系统中整合Reports Services(转)

1 Reporting Services简介

      微软公司的SQL Server™ 2000 Reporting Services是为企业报表提供解决方案的一款产品。该产品由报表服务器和报表设计器两部分组成,用户可以使用报表设计器直接定制报表,生成的报表在报表服务器上采用Web页面的方式进行发布。Reporting Services为企业信息化实施过程中,克服制作报表困难提供了一个有力工具,可以缓解企业信息化过程中,业务部门对IT部门的需求压力,改善整个企业获取信息的速度和质量。

2 在应用系统中访问报表的问题

      用户使用Reporting Services报表设计器将设计好的报表部署到报表服务器后,在浏览器中输入报表的地址,经过Windows验证就可以访问到报表。这种状况下,应用系统与Reporting Services报表服务器之间是相互独立的。这种访问报表的方式对于已经建立了应用系统的用户至少会感到三点很不便,一是要在应用系统外来访问需要的报表;其次要经过Windows验证,需要用户再次输入用户名和口令;再有就是Reporting Services对报表的访问控制是基于“角色”来进行的,对于分层树状组织结构的企业,这种控制方式难以令人满意,而希望将报表的访问控制放在应用系统中来解决,以便实施更细致的安全策略。

3 整合方案

      针对上述问题,在应用系统和Reporting Services之间构建一个中间网站, 整合中间网站和报表服务器网站的验证机制,使得整个系统对外呈现的安全特性是:用户在浏览器中直接输入URL是不能访问中间网站的页面和报表服务器上部署的报表,只有通过应用系统网站的有关页面才能访问到Reporting Services部署的报表。如下图1所示:只有用户请求1经过应用系统后可以访问到报表,而用户请求2和用户请求3则不能访问到报表。将用户对报表的访问控制机制放到应用系统中。
      构建中间网站可以使用Reporting Services提供的呈现报表组件ReportViewer,利用该组件将报表集成到应用环境中,为用户提供一致的操作环境。
      同时考虑到对报表服务器安全性设置进行改动会使得报表管理器使用不正常。应该将这种影响降低到最小。而对应用系统,如果不是采用ASP.NET技术构建的,那么也不能直接使用ReportViewer组件,只有采用过渡机制。如果是采用ASP.NET技术构建的应用系统,则可以依据实际情况对构架做出调整。

图1 整合方案构架示意图

4 实施方法

4.1 配置报表服务器

       (1)在安装Reporting Services的服务器的操作系统下新建一个本地用户并将其隶属于User或Guest组。
       (2)进入Reporting Services的报表管理器,在“新建角色分配\新建角色”操作中建立一个新角色,仅分配“查看报表”一项任务。在“新建角色分配”操作中,输入新建本地用户名字并且将新建角色分配给该用户。
      (3)启动Internet服务管理器,在默认Web站点下选择ReportServer站点,将新建的本地用户设置为匿名用户访问时使用的账户,同时选择“允许IIS控制密码”。

4.2 建立一个中间站点并进行配置

      (1)修改该站点的Web.config文件,将<authentication>节中的验证模式改为Forms方式,将<authorization>节中URL 授权设置为拒绝匿名用户。需要修改的配置如下所示:
<authentication mode="Forms">
                   <forms loginUrl="Logon.aspx" name="AuthCookie" timeout="60" path="/">
                   </forms>
         </authentication>
<authorization>
<deny users="?" />   <!-- 拒绝匿名用户 -->
<allow users="*" /> <!-- 允许所有用户 -->   
</authorization>
这样将只允许通过身份验证的用户访问中间站点中页面,而<authentication>建立的 loginUrl 属性会将未通过身份验证的请求重定向到 Logon.aspx 页。
      (2)建立Logon.aspx页,在这个页面中可以依据实际情况采用应用服务器的特殊标志(如IP地址、服务器名字等)制作一个身份票证,并将其写到客户端,使得用户访问该网站下的页面不再需要进行身份验证。
public class WebForm1 : System.Web.UI.Page
{
     private void Page_Load(object sender, System.EventArgs e)
     {
              // 在此处放置用户代码以初始化页面
              NameValueCollection coll;
              coll=Request.ServerVariables;
serverip=coll.Get("LOCAL_ADDR");                               // 例如:得到服务器IP地址
If (IsAuthenticated(serverip)==true)
              {
                       // 创建新的非永久性Forms身份验证票证,它包含服务器名、IP、到期时间。
                       // 用服务器名字和IP地址定义一个标志。
                       string userdata=serverip;
                       FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
                                 1,                                                                                 //版本号。
                                 servername,                                                                 //与身份验证票关联的用户名。
                                 System.DateTime.Now,                                             //Cookie 的发出时间。
                                 System.DateTime.Now.AddMinutes(60),        //Cookie 的到期日期。
                                 false,                                                                   //非持久的票证。
                                 userdata,                                                                      //用户定义数据。
                                 FormsAuthentication.FormsCookiePath);         //Cookie 的路径。
// 为该票证加密,并将它作为数据存储在 HttpCookie 对象内。
                       string encryptedTicket = FormsAuthentication. Encrypt(authTicket);
                       // 创建一个 cookie 并将加密的票证添加到该 cookie 作为数据。
HttpCookie authCookie = new
HttpCookie(FormsAuthentication.FormsCookieName,encryptedTicket);
                       // 将 cookie 添加到返回给用户浏览器的 cookie 集合中。
                       Response.Cookies.Add(authCookie);
                       // 将用户重定向到最初请求的页面。
Response.Redirect(FormsAuthentication.GetRedirectUrl(servername,false ));
                       }
              else
                       Response.Write("你没有权限访问该页面,请联系系统管理员。"+"<br>");
              }
              // 验证方法:如果通过验证,则返回true,否则返回false。
              private bool IsAuthenticated(string serverflag)
              {
                       //用户验证:对服务器标志进行验证,检查是否为来自应用服务器的请求。
              }
     }
}
确保以下代码在 Web 窗体设计器生成代码的 InitializeComponent 方法中。
this.Load += new System.EventHandler(this.Page_Load);

4.3 使用ReportViewer组件建立中间页面

      (1)在Reporting Services安装目录下查找ReportViewer解决方案文件ReportViewer.sln。如:<安装盘>\Program Files\Microsoft SQL Server\MSSQL\Reporting Services\Samples\Applications\ReportViewer。此目录下有两个子目录,一个是基于C#的,另一个是基于VB的。根据实际应用情况选取一个。
     (2)在Visual Studio .NET中打开ReportViewer.sln文件,然后在菜单中选择生成解决方案。
     (3)在Visual Studio .NET打开中间站点的解决方案。
上接第76页
     (4)点击工具箱,选择“增加/移除项”打开自定义工具箱窗口。选择“.NET Framework组件”标签页。用浏览定位<安装盘>\Program Files\Microsoft SQL Server\MSSQL\Reporting Services\Samples\Applications\ReportViewer\bin\Release目录下的ReportViewer.dll,将其加入到工具箱中。
     (5)在工具箱中选择ReportViewer组件,将其拖动到页面中,在属性窗口设置ServerUrl的值为报表服务器的地址(如http://localhost/reportserver);设置ReportPath的值为已经部署到报表服务器的报表地址(如/Samples/MyReport)。如果需要,也可以设置Parameters、Toolbar、Zoom、Size等属性值。

4.4在应用系统中使用报表

      在应用系统中链接中间网站中的页面,这样就可以根据应用系统对报表的权限策略来访问报表。

5 结束语

     方案结构清晰,实施和维护比较方便。同时,由于整合了Windows的验证机制,用户在应用系统中对报表的访问呈现出一站式登录的效果,改进了原有访问Reporting Services报表进行验证给用户带来的不便。对报表服务器和中间网站做了安全性考虑,并且采取了一定措施,将报表访问的控制权限交给了应用系统,以便于用户实施更灵活和细致的权限策略。对于已经建立应用系统,并试图使用Reporting Services来增强系统的报表功能的用户,不失为具有一定实用性的解决方案。
方案的不足之处是当需要使用报表管理器时,要将报表服务器的身份验证恢复为默认方式,即去掉报表服务器的匿名访问方式。

参考文献

1         Microsoft,《如何创建自定义帐户来运行 ASP.NET》,
2 Microsoft,《如何使用 Forms 身份验证创建 GenericPrincipal 对象》,
3 John C. Hancock,《Deliver User-Friendly Reports from Your Application with SQL Server Reporting Services》,
4 Microsoft,《ReportViewer自述文件》
posted @ 2008-08-20 13:42  jame_peng  阅读(439)  评论(0编辑  收藏  举报