将服务器凭据传递给 SSRS

Passing server credentials to SSRS

我在我的一个 asp 项目中有一个函数,它会访问服务器以获取报告并 returns 字节。到目前为止,我一直在使用我的域凭据,但希望在服务器本身上使用 sql 服务器身份验证,但无论如何我都会收到 401 错误。

public byte[] GetReportBytes(string report, string parameterList)
    {
        string strReportUser = "sqlserveruser";
        string strReportUserPW = "password";
        //not used with sql?
        string strReportUserDomain = "domain";

        string sTargetURL = "reportserver?" +
                            "/folder/" + report + "&rs:Command=Render&rs:format=PDF&" + parameterList;

        HttpWebRequest req =
              (HttpWebRequest)WebRequest.Create(sTargetURL);
        req.PreAuthenticate = true;
        req.Credentials = new System.Net.NetworkCredential(
            strReportUser,
            strReportUserPW);

        HttpWebResponse HttpWResp = (HttpWebResponse)req.GetResponse();

        Stream fStream = HttpWResp.GetResponseStream();
        byte[] fileBytes = ReadFully(fStream);
        return fileBytes;
    }

这可能吗?

我认为您无法使用 "sql server authentication" 对 Reporting Services Web url 进行身份验证(至少开箱即用)。 (您的 数据源 可以,但这里我们讨论的是 SSRS 网址)。 "Sql Server Authentication" 未被列为 Authentication with the Report Server

支持的方法之一

如果你愿意,你可以Configure Custom or Forms Authentication on the Report Server

您也可以 Configure Basic Authentication on the Report Server,但即使这样也不会使用 "sql server authentication" - 请求会被传递到本地安全机构,最终可能会验证域凭据。

在你的例子中,看起来你的网络应用程序本质上是一个代理(在某种意义上)——它正在获取报告作为一个代表 pdf 的字节数组,并返回它,这样客户端浏览器就永远不会实际上直接与SSRS通信。

因此,为此,我建议只保留 windows 身份验证,并设置 SSRS 权限,以便您委托使用 asp.net 应用程序池的身份(并保留该应用程序特定于您的特定应用程序的池)。这样,您就不需要在 Web 应用程序代码或配置中存储任何用户名或密码。

为此,您还需要在 SSRS 中设置至少具有 "Content Browser" 权限的应用程序池身份用户。除非您的 iis 实例与您的报告服务服务器位于同一台机器上,否则您将需要创建一个权限有限的域用户,或镜像本地帐户以设置为您的应用程序池标识。 (或者,如果你真的想使用内置的 IIS ApplicationPoolIdentity 用户,你可以授予计算机帐户的 SSRS 权限(例如 <domain>\<machinename>$)但是,这可能并不理想,因为它授予了很多更广泛地访问哪些服务可以访问 SSRS)。

如果您的 Web 应用程序使用表单身份验证,则只需执行以下操作即可:

 req.Credentials = System.Net.CredentialCache.DefaultCredentials;

但是,如果您对网站使用 windows 身份验证,上述(如果没记错的话)将传递当前登录的 windows 用户的身份,而不是应用程序池标识,这可能不是您想要的。

使用 SSRS 网络服务

如果您愿意使用 SSRS Web 服务并在您的项目中使用 "Add Service Reference" 生成 soap 客户端(您的示例代码不会这样做),您可以使用应用程序池进行身份验证通过执行以下操作来标识:

 var soapClient = new ReportExecutionServiceSoapClient("ReportExecutionServiceSoap");
 soapClient.ClientCredentials.Windows.AllowedImpersonationLevel = 
                            System.Security.Principal.TokenImpersonationLevel.Delegation;

我已经有一段时间没有这样做了,但是在使用 "Service Reference" 时,您还需要确保 WCF 绑定是正确的。以下是我认为上次对我有用的内容:

<system.serviceModel>
<bindings>
  <basicHttpBinding>
    <binding name="ReportExecutionServiceSoap" allowCookies="true" maxReceivedMessageSize="5242880">
      <security mode="Transport">
        <transport clientCredentialType="Ntlm" proxyCredentialType="None" realm="" />
        <message clientCredentialType="Certificate" algorithmSuite="Default" />
      </security>
    </binding>
  </basicHttpBinding>
</bindings>
<client>
  <endpoint address="https://theSsrsServer/ReportServer/ReportExecution2005.asmx" binding="basicHttpBinding" bindingConfiguration="ReportExecutionServiceSoap" contract="ReportService.ReportExecutionServiceSoap" name="ReportExecutionServiceSoap" />
</client>

不,这是不可能的。使用 windows 凭据。