代码之家  ›  专栏  ›  技术社区  ›  Jarrett Meyer

SSRS报表查看器+ASP.NET凭据401异常

  •  7
  • Jarrett Meyer  · 技术社区  · 15 年前

    我在SQL2005报表服务器上保存了一个报表,我希望返回此报表的已呈现PDF。我在处理本地的*.rdlc文件时就发现了这个问题。( and I've blogged about it ,但不是当*.rdl驻留在报表服务器上时。我得到一个 401未授权 行出错…

    reportViewer.ServerReport.SetParameters(reportDefinition.ReportParameters);
    

    下面是用于呈现报告的方法。

    public byte[] Render(IReportDefinition reportDefinition)
    {
        var reportViewer = new ReportViewer();
        byte[] renderedReport;
        try
        {
            var credentials = new WindowsImpersonationCredentials();
            reportViewer.ServerReport.ReportServerUrl = new Uri("http://myssrsbox", UrlKind.Absolute);
            reportViewer.ServerReport.ReportServerCredentials = credentials;
            reportViewer.ServerReport.ReportPath = reportDefinition.Path;
            // Exception is thrown on the following line...
            reportViewer.ServerReport.SetParameters(reportDefinition.ReportParameters);
    
            string mimeType;
            string encoding;
            string filenameExtension;
            string[] streams;
            Warning[] warnings;
    
            renderedReport = reportViewer.ServerReport.Render(reportDefinition.OutputType, reportDefinition.DeviceInfo, out mimeType, out encoding, out filenameExtension, out streams, out warnings);
        }
        catch (Exception ex)
        {
            // log the error...
            throw;
        }
        finally
        {
            reportViewer.Dispose();
        }
        return renderedReport;
    }
    

    另一件丢失的是WindowsImpersonationCredentials类。

    public class WindowsImpersonationCredentials : IReportServerCredentials
    {
        public bool GetFormsCredentials(out Cookie authCookie, out string userName, out string password, out string authority)
        {
            authCookie = null;
            userName = password = authority = null;
            return false;
        }
    
        public WindowsIdentity ImpersonationUser
        {
            get { return WindowsIdentity.GetCurrent(); }
        }
    
        public ICredentials NetworkCredentials
        {
            get { return null; }
        }
    
        public override string ToString()
        {
            return String.Format("WindowsIdentity: {0} ({1})", this.ImpersonationUser.Name, this.ImpersonationUser.User.Value);
        }
    }
    

    你可能需要知道的其他事情…

    • 这是在Intranet上运行的,并且模拟已打开。
    • 日志记录指示正在正确设置模拟用户。
    • 这个 做功 在Visual Studio中运行时( http://localhost:devport ) 做功 在我的开发盒上运行时( http://localhost/myApplication )它 不起作用 在我们的测试或生产服务器上运行时。
    • 我尝试过在web.config中使用或不使用system.net.defaultproxy设置的解决方案。两者都不起作用。

    我做错什么了?是服务器设置吗?是代码吗?是web.config吗?

    2 回复  |  直到 15 年前
        1
  •  6
  •   Jarrett Meyer    15 年前

    我们终于解决了这个问题。我们的网络管理员已禁用双跳,因此当模拟作为 domain\jmeyer ,应用程序仍在尝试使用连接到SRS盒 domain\web01$ . 为什么要这样设置?因为双跳是一个巨大的安全漏洞。(有人告诉我。这听起来像你要读的东西吗 The Daily WTF ?)

    我们的解决方案是创建一个通用的 domain\ssrs_report_services 用户,并使用以下网络凭据与该用户连接

    public class CustomCredentials : IReportServerCredentials
    {
        public bool GetFormsCredentials(out Cookie authCookie, out string userName, out string password, out string authority)
        {
            authCookie = null;
            userName = password = authority = null;
            return false;
        }
    
        public WindowsIdentity ImpersonationUser
        {
            get { return null; }
        }
    
        public ICredentials NetworkCredentials
        {
            get { return new NetworkCredential("ssrs_report_services", "password", "domain") ; }
        }    
    }
    

    上面是一个经典的例子,你可以在互联网上找到。

        2
  •  2
  •   Jim Ryder    15 年前

    允许“双跳”—使用Kerberos身份验证…(只要工作正常!)