【问题标题】:pass authentication header to image requests in iframe将身份验证标头传递给 iframe 中的图像请求
【发布时间】:2013-04-25 10:53:27
【问题描述】:

我确信我的问题的标题没有多大意义,但我现在想不通。

问题:我的主要任务是在 ASP.NET MVC 应用程序的一个页面内的弹出窗口中显示 SSRS 报告的所有页面

为了实现这一点,我使用了以下方法:

  1. 在 MyPage.cshtml 中添加一个 jQuery 弹出窗口(我需要在这个弹出窗口中报告内容)
  2. 当此弹出窗口打开时(在某些客户端操作上),我向第二页 proxyPage.aspx 发出 jquery ajax 请求
  3. 在代理页面上,我使用网络凭据向报告服务器发出网络请求并获取报告 html

        WebRequest request = WebRequest.Create( "http://MyReportServer/ReportServer?/ MyReportName&rs:Command=Render&rs:Format =HTML4.0&rc:Toolbar=false&Param1=blabla123");
        request.Credentials = new NetworkCredential(MYUSERNAME, MYPASSWORD);
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        Stream receiveStream = response.GetResponseStream();
        StreamReader readStream = new StreamReader(receiveStream, System.Text.Encoding.UTF8);
        string str = readStream.ReadToEnd();
        Response.Write(str);
    
  4. 来自 proxyPage 的 HTML 我写在弹出窗口内的 div 中或使用 iframe 在其中显示完整的代理页面。

  5. 直到这里一切顺利,然后我又遇到了另一个问题,我正在写这个问题

  6. 当报表的 HTML 在弹出窗口中呈现时,它会向报表服务器发出请求以检索报表中嵌入的图像。

由于这些对报告服务器的请求没有像我在步骤 3 中那样发送网络凭据,因此我会收到输入凭据的提示。

我需要一种方法,通过这种方法,这些图像请求可以通过我之前提供的凭据以某种方式进行身份验证。

【问题讨论】:

    标签: asp.net ssrs-2008 reporting-services windows-authentication basic-authentication


    【解决方案1】:

    SSRS 将在您指定的位置流式传输资源。

    private byte[] InternalRenderReport(Report report, List<ReportParameter> parameters, string format, int pageNumber, ref int totalPages, string virtualTempFolder, string physicalTempFolder)
            {
                CheckConnection();
                byte[] result = null;
                ReportExecution2005.ReportExecutionService _execService=new ReportExecution2005.ReportExecutionService();
    
    
                sys = _systemService.GetCurrentSystem();
                _execService.Url = sys.ReportingServices.ServiceRootURL+"/ReportExecution2005.asmx";
                NetworkCredential credentials = new NetworkCredential(sys.ReportingServices.Credentials.UserName, 
                                                                     sys.ReportingServices.Credentials.Password,
                                                                     sys.ReportingServices.Credentials.Domain);
                _execService.Credentials=credentials;
    
                ReportExecution2005.ParameterValue[] rsParams = null;
                if (parameters != null)
                {
                    rsParams = new ReportExecution2005.ParameterValue[parameters.Count];
                    int x = 0;
                    foreach (ReportParameter p in parameters)
                    {
                        rsParams[x] = new ReportExecution2005.ParameterValue();
                        rsParams[x].Name = p.ParameterName;
                        rsParams[x].Value = p.SelectedValue;
                        x++;
                    }
                }
                StringBuilder devInfo = new StringBuilder();
                if (format.ToUpper().StartsWith("HTML"))
                {
                    devInfo.Append("<DeviceInfo>");
                    devInfo.Append("<HTMLFragment>True</HTMLFragment>");
                    devInfo.Append("<Section>" + pageNumber.ToString() +"</Section>");
                    devInfo.Append("<StreamRoot>" + virtualTempFolder + "</StreamRoot>");
                    /*devInfo.Append("<Zoom>200</Zoom>");*/
                    devInfo.Append("</DeviceInfo>");                
                }
                else
                     devInfo.Append("<DeviceInfo><Toolbar>False</Toolbar></DeviceInfo>");
    
                string extension;
                string mimeType;
                string encoding;
                string[] streamIDs = null;
                ReportExecution2005.Warning[] warnings = null;
    
    
    
    
                ReportExecution2005.ExecutionHeader execHeader = new ReportExecution2005.ExecutionHeader();
                ReportExecution2005.ExecutionInfo rpt = _execService.LoadReport(report.ReportPath, null);
    
                if(rsParams!=null)
                    _execService.SetExecutionParameters(rsParams, "en-us");
                _execService.ExecutionHeaderValue = execHeader;
                _execService.ExecutionHeaderValue.ExecutionID = rpt.ExecutionID;
    
    
                //result = _execService.Render2(format, devInfo, ReportExecution2005.PageCountMode.Actual, out extension, out mimeType, out encoding, out warnings, streamIDs);
                result =  _execService.Render(format, devInfo.ToString(), out extension, out mimeType, out encoding, out warnings, out streamIDs);
    
                if (format.ToUpper().StartsWith("HTML"))
                {
    
    
                    // For each image stream returned by the call to render,
                    // render the stream and save it to the application root
                    string FilePath = physicalTempFolder;
                    byte[] image;
                    // For each image stream returned by the call to render,
                    // render the stream and save it to the application root
                    foreach (string streamID in streamIDs)
                    {
                        image = _execService.RenderStream("HTML4.0", streamID, null, out encoding, out mimeType);
    
                        FileStream stream = File.OpenWrite(FilePath + streamID);
                        stream.Write(image, 0, image.Length);                    
                        stream.Close();
                    }
                }
    
                rpt = _execService.GetExecutionInfo();
                totalPages = rpt.NumPages;
    
                return result;
            }
    

    这将返回原始 HTML 或内容以推送文件。我在要部署到服务器的解决方案中添加了一个 Temp 文件夹。您可以在 temp 文件夹中放置一个 web.config 文件,其中包含以下内容,以允许扩展更少的内容,因为 ssrs 在使用流时将呈现:

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
      <system.webServer>
        <staticContent>
    
          <mimeMap fileExtension=".*" mimeType="image/png" />
    
    
        </staticContent>
        <handlers>
          <clear />
    
          <add name="StaticFile" path="*" verb="*" type="" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" scriptProcessor="" resourceType="Either" requireAccess="Read" allowPathInfo="false" preCondition="" responseBufferLimit="4194304" />
        </handlers>
      </system.webServer>
    </configuration>
    

    然后使用以下函数获取物理和虚拟临时文件夹:

    PhyscicalTempFolder= AppDomain.CurrentDomain.BaseDirectory + @"Temp\";
    VirtualTempFolder=return  Url.Content("~/Temp/");
    

    最后每天清理后可以添加类似以下的powershell命令:

    Remove-Item D:\xxx\WebApplications\ExternalReports\Temp\* -exclude *.config
    

    然后添加一个调用PS脚本的.bat:

    powershell -command "& 'C:\xxx\Scripts\SSRSCleanTempFiles\SSRSCleanTempFiles.ps1'"
    

    这样你可以在服务器上配置一个计划任务来每天调用 .bat 文件并清理你的应用程序的临时文件夹。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-15
      • 2019-02-02
      • 2012-09-22
      相关资源
      最近更新 更多