SQL SERVER 2008中,Reporting Service不再依赖于IIS,这带来很多利处,不过这也意味着不能够直接通过配置IIS的虚拟目录部署来实现匿名访问了。下面我们就看一下在SSRS 2008中怎么能够实现报表的“匿名访问”,不过对于一个正式项目来说,建议不要并且从不允许匿名来访问报表。
1. 实现IReportServerCredentials接口
对于使用Asp.Net的ReportViewer控件,实现IReportServerCredentials接口来实现自定义身份验证,然后通过设置成ReportView的属性ServerReport.ReportServerCredentials。此接口的定义:
public interface IReportServerCredentials { WindowsIdentity ImpersonationUser { get; } ICredentials NetworkCredentials { get; } bool GetFormsCredentials(out Cookie authCookie, out string userName, out string password, out string authority); } public interface IReportServerCredentials { WindowsIdentity ImpersonationUser { get; } ICredentials NetworkCredentials { get; } bool GetFormsCredentials(out Cookie authCookie, out string userName, out string password, out string authority); } |
此接口定义了三种身份验证的方式来访问Report Server,可以单独使用,也可以组合使用这三种方式。
ImpersonationUser:ReportView在每次WebRequest请求到ReportServer前模拟的一个WindowsIdentity,实际上会调用这个属性的WindowsIdentity.Impersonate方法来完成。如果此属性返回null的话,则默认使用当前线程用户。
NetworkCredentials: 此属性的值将会经由WebRequest.Credentials属性直接传递给WebRequest,如果返回null的话,则默认是CredentialCache.DefaultCredentials,使用当前上下文的系统凭据,这也是通常我们使用的方式。
GetFormsCredentials:这是ReportServer特有的认证体系,如果返回true的话,输出参数将用来调用ReportServer上的LogonUser方法,这个方法是用来支持服务器上的安全扩展插件。
这个接口是如何被使用的呢,我们从report viewer说起。当ASPX page页面执行时,ReportView控件并不是一次性的请求ReportServer。这其间其实需要通过ReportViewer HTTP handler多次请求Report Server.就比如报表中显示一个图片,在客户端生成的html中有图片标签,对于其中的图片会请求ReportView控件,ReportView收到请求后会重新请求ReportServer索要这个图片,ReportServer这时还需要判断当前请求的用户是否和初始的用户一一致,如果一致才会返回图片。其它的例如ReportView提供的打印,导出也是同样的原理。
ReportView控件的IReportServerCredentials的实例的属性,存储在Asp.net SessionState中,这样即保证了安全性,又能够即时的获取到认证信息。不过这个接口提供的灵活性使我们在设置这个凭据时更加灵活,我们可以如下实现:
[Serializable] class MyConfigFileCredentials : IReportServerCredentials { public MyConfigFileCredentials() { } public WindowsIdentity ImpersonationUser { get { return null; } } public ICredentials NetworkCredentials { get { return new NetworkCredential( ConfigurationManager.AppSettings[“MyUserName”], ConfigurationManager.AppSettings[“MyPassword”]); } } public bool GetFormsCredentials(out Cookie authCookie, out string userName, out string password, out string authority) { authCookie = null; userName = null; password = null; authority = null; } } [Serializable] class MyConfigFileCredentials : IReportServerCredentials { public MyConfigFileCredentials() { } public WindowsIdentity ImpersonationUser { get { return null; } } public ICredentials NetworkCredentials { get { return new NetworkCredential( ConfigurationManager.AppSettings[“MyUserName”], ConfigurationManager.AppSettings[“MyPassword”]); } } public bool GetFormsCredentials(out Cookie authCookie, out string userName, out string password, out string authority) { authCookie = null; userName = null; password = null; authority = null; } } |
上面我们只提供第二种认证方式,创建一个NetwrokCredential实例,并且采用配置文件中存储的用户名和密码,可以在后期修改。在配置文件中创建两个参数的值为能够正常访问此报表的帐号和密码,然后给赋值给ReportView的属性即可:
ReportViewer1.ServerReport.ReportServerCredentials = new MyConfigFileCredentials();
ReportViewer1.ServerReport.ReportServerCredentials = new MyConfigFileCredentials();
这样,当你浏览报表程序时,就不会提示输入用户名和密码了。或许你看到这里应该也意识到了,我们所说的匿名访问报表,并不是说报表设置给了everyone都可以访问,而是说我们包装了一下,省略了用户认证这一步,而模拟成了一个可以访问的用户,来实现的“匿名访问”。其实在先前使用IIS作为报表服务器的时候,也是通过在IIS中设置虚拟目录或者网站,来实现了这个模拟的动作。
2.实现IReportServerConnection接口
但是如果你的系统中禁止SessionState怎么办呢。这时你可以考虑实现IReportServerConnection 或者IReportServerConnection2 接口:
public interface IReportServerConnection : IReportServerCredentials { Uri ReportServerUrl { get; } int Timeout { get; } } public interface class IReportServerConnection2 : IReportServerConnection, IReportServerCredentials { IEnumerable Cookies {get;} IEnumerable Headers {get;} } public interface IReportServerConnection : IReportServerCredentials { Uri ReportServerUrl { get; } int Timeout { get; } } public interface class IReportServerConnection2 : IReportServerConnection, IReportServerCredentials { IEnumerable Cookies {get;} IEnumerable Headers {get;} } |
从这两个接口的代码可以看出,他们的实例可以当做IReportServerCredentials来使用,所以上面介绍的方法对于他们们的实现同样管用。他们的属性值同样默认存储在SessionState中,当SessionState禁止时,我们要提供其它的访问方式,以下是我们的实现:
view plaincopy to clipboardprint [Serializable] public class MyReportServerConnection : IReportServerConnection2 { public Uri ReportServerUrl { get { string url = ConfigurationManager.AppSettings[“MyReportServerUrl”]; if (string.IsNullOrEmpty(url)) throw new Exception(“Missing url from the Web.config file”); return new Uri(url); } } public int Timeout { get { return 60000; } } public IEnumerable Cookies { get { return null; } } public IEnumerable Headers { get { return null; } } public MyReportServerConnection() { } public WindowsIdentity ImpersonationUser { get { return null; } } public ICredentials NetworkCredentials { get { string userName = ConfigurationManager.AppSettings”[myReportViewerUser]; if (string.IsNullOrEmpty(userName)) throw new Exception(“Missing user name from Web.config file”); string password = ConfigurationManager.AppSettings[“MyReportViewerPassword”]; if (string.IsNullOrEmpty(password)) throw new Exception(“Missing password from Web.config file”); string domain = ConfigurationManager.AppSettings[“MyReportViewerDomain”]; if (string.IsNullOrEmpty(domain)) throw new Exception(“Missing domain from Web.config file”); return new NetworkCredential(userName, password, domain); } } public bool GetFormsCredentials(out Cookie authCookie,out string userName,out string password,out string authority) { authCookie = null; userName = null; password = null; authority = null; return false; } } [Serializable] public class MyReportServerConnection : IReportServerConnection2 { public Uri ReportServerUrl { get { string url = ConfigurationManager.AppSettings[“MyReportServerUrl”]; if (string.IsNullOrEmpty(url)) throw new Exception(“Missing url from the Web.config file”); return new Uri(url); } } public int Timeout { get { return 60000; } } public IEnumerable Cookies { get { return null; } } public IEnumerable Headers { get { return null; } } public MyReportServerConnection() { } public WindowsIdentity ImpersonationUser { get { return null; } } public ICredentials NetworkCredentials { get { string userName = ConfigurationManager.AppSettings”[myReportViewerUser]; if (string.IsNullOrEmpty(userName)) throw new Exception(“Missing user name from Web.config file”); string password = ConfigurationManager.AppSettings[“MyReportViewerPassword”]; if (string.IsNullOrEmpty(password)) throw new Exception(“Missing password from Web.config file”); string domain = ConfigurationManager.AppSettings[“MyReportViewerDomain”]; if (string.IsNullOrEmpty(domain)) throw new Exception(“Missing domain from Web.config file”); return new NetworkCredential(userName, password, domain); } } public bool GetFormsCredentials(out Cookie authCookie,out string userName,out string password,out string authority) { authCookie = null; userName = null; password = null; authority = null; return false; } } } |
要使HTTP handler在不存储的情况下还能够访问它,必须还要添加ReportView的WebConfig配置:
view plaincopy to clipboardprint
同样的,我们直接赋值给ReportView的属性,就可以实现报表的“匿名访问”。
view plaincopy to clipboardprint
this.ReportViewer1.ServerReport.ReportServerCredentials = new MyReportServerConnection();
我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。
我原创,你原创,我们的内容世界才会更加精彩!
【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】
微信公众号
TechTarget
官方微博
TechTarget中国
作者
相关推荐
-
SQL Server 2016 即将发布 你准备好了吗?
SQL Server 2016即将推出一系列全新的内置特性,并对数据库管理员所依赖的某些非常重要但十分单调的功能进行了改进。
-
SQL Server 2008将退出微软主流数据库支持
你的企业是否还在运行SQL Server 2008?请注意微软为SQL Server 2008提供的主流技术支持服务将于今年的7月8日正式结束。
-
微软数据挖掘开发:模型的验证与展示
通常情况下,针对某个特定案例,我们不能准确定位哪个挖掘算法是最准确的,所以我们会通过对多个挖掘模型的验证,得出最准确的那个。
-
SSRS最佳实践:无忧部署
虽然SQL Server报表服务(SSRS)平台并不难学习,但它仍然是一种相当复杂的技术。SSRS的成功运用需要数据库、管理学、报表构建和数据分析的组合能力。