【问题标题】:Authenticating against ReportExecution2005.asmx in .NET Core针对 .NET Core 中的 ReportExecution2005.asmx 进行身份验证
【发布时间】:2022-03-12 07:05:42
【问题描述】:

我正在尝试在 .NET Core 中执行 SSRS 报告。

由于 .NET Core 不允许您添加服务引用,因此您必须使用 WCF 连接服务来添加对 WSDL 的引用,以便它可以生成与 .NET Core 兼容的代码。这就是我为 ReportExecution2005.asmx 所做的(如果重要,可以使用 SQL Server 2016)。

我尝试使用以下方法对服务进行身份验证:

var rsExec = new ReportExecutionServiceSoapClient(ReportExecutionServiceSoapClient.EndpointConfiguration.ReportExecutionServiceSoap,
                                                  new EndpointAddress("http://server/ReportServer/ReportExecution2005.asmx"))
                    {
                        ClientCredentials =
                        {
                            Windows =
                            {
                                AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation,
                                ClientCredential = new NetworkCredential("username", "password")
                            }
                        }
                    };

还尝试设置用户名对象而不是 Windows 对象,但无论哪种方式结果都是以下错误:

MessageSecurityException:HTTP 请求未经客户端身份验证方案“匿名”授权。从服务器收到的身份验证标头是“NTLM”。

查看 Fiddler,代码没有传递凭据。

这是从 WSDL 生成的代码

public ReportExecutionServiceSoapClient(EndpointConfiguration endpointConfiguration, System.ServiceModel.EndpointAddress remoteAddress)
   : base(ReportExecutionServiceSoapClient.GetBindingForEndpoint(endpointConfiguration), remoteAddress)
{
    this.Endpoint.Name = endpointConfiguration.ToString();
    ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
}

static partial void ConfigureEndpoint(System.ServiceModel.Description.ServiceEndpoint serviceEndpoint, System.ServiceModel.Description.ClientCredentials clientCredentials);

我可能弄错了,但这不是在设置 ClientCredentials 对象之前使用 ClientCredentials 对象调用私有方法 ConfigureEndpoint 吗?

我没有看到任何其他方式来配置 ClientCredentials 或调用 ConfigureEndpoint,那么您应该如何进行身份验证?其他构造函数基本上是相同的,除了一个接受 Binding 而不是 EndpointConfiguration 的构造函数。有什么想法吗?

【问题讨论】:

  • 另外,我知道我可以将它放入 .NET Framework 库并从那里引用它,但我想尝试使用 .NET Core 让它工作。
  • 您的安全模型是如何设置的?您是否在 ssrs 实例上使用本地用户向 ssrs 请求?如果是,该用户是否有权这样做?
  • 另一件事是检查您的 wfc 绑定的传输安全配置。
  • @RossBush,是有权限的本地账号。我在 .NET 4.6 和等效代码下使用相同的凭据测试了该服务,并且能够毫无问题地执行报告。至于 WCF 绑定,恐怕我实际上对此并不了解。我没有修改服务器本身的任何东西,几乎只是使用默认选项安装了 SSRS。

标签: c# web-services reporting-services .net-core


【解决方案1】:

在与这个问题斗争了一天之后,我发现了一种似乎可行的方法,方法是使用问题中指出的唯一不会立即调用 ConfigureEndpoint 的构造函数。如果我创建一个指定 NTLM 的绑定,并将该绑定与手动创建的端点一起传递,它可以工作:

var binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly)
{
    Security =
    {
        Transport = new HttpTransportSecurity {ClientCredentialType = HttpClientCredentialType.Ntlm}
    }
};

var reportService = new CssbiReportService.ReportExecutionServiceSoapClient(binding,
    new EndpointAddress("http://myserver/ReportServer/ReportExecution2005.asmx"));

这在 .NET Core 中对我有用。

【讨论】:

    【解决方案2】:

    编辑:更新 .NET Core 的代码

    很遗憾,我现在没有 SSRS 来测试代码。

    但是,试试这个代码(没有错误检查):

    // parameters of report (if any)
    ParameterValue[] parameters = {new ParameterValue {Name = "ApontamentoID", Value = "364"}};
    
    // connect to the service
    ReportExecutionServiceSoapClient webServiceProxy =
      new ReportExecutionServiceSoapClient(
        ReportExecutionServiceSoapClient.EndpointConfiguration.ReportExecutionServiceSoap,
        "http://report_server_url/ReportExecution2005.asmx?wsdl");
    
    // logon the user
    await webServiceProxy.LogonUserAsync("username", "password", null);
    
    // ask for the report
    await webServiceProxy.LoadReportAsync("/report_path", null);
    await webServiceProxy.SetExecutionParametersAsync(parameters, null);
    
    // you can use RenderStreamRequest too
    RenderRequest request = new RenderRequest("pdf", null);
    RenderResponse response = await webServiceProxy.RenderAsync(request);
    
    // save to the disk
    System.IO.File.WriteAllBytes(@"c:\temp\output.pdf", response.Result);
    
    // logoff the user
    await webServiceProxy.LogoffAsync();
    
    // close
    await webServiceProxy.CloseAsync();
    

    【讨论】:

    • 这是 .NET Core 代码吗?我不能将 ReportExecutionserviceSoapClient 放在 using 语句中,因为它没有实现 IDisposable。
    • 操作。对不起!现在我读到你正在使用.net core!我的错!我正在使用 NET 4.6.1。
    • 我更新代码!你能检查一下吗?也许缺少一些东西,但我没有找到任何示例或更好的文档(比如关于 ssrs 的所有内容)。
    • 感谢您的更新。当我调用 LogonUserAsync 时,我得到了原始问题中提到的相同错误。看来我必须经过身份验证才能调用该方法。
    【解决方案3】:
    var binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly)
    {
        Security =
        {
            Transport = new HttpTransportSecurity {
               ClientCredentialType = HttpClientCredentialType.Ntlm
            }
        }
    };
    
    
    yourClient = ReportExecutionServiceSoapClient(rsBinding, rsEndpointAddress) {
                    ClientCredentials =
                    { ...
    
    

    ^^^ 这适用于 NTLM。

    此外,我在客户端创建后尝试在客户端上设置某些属性时遇到只读错误。如果它对某人有帮助,则必须在客户端创建时设置所有属性,以避免按照上面的“yourClient”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-06
      • 2020-01-14
      • 2019-04-24
      • 2018-12-17
      • 2020-10-28
      • 2020-10-15
      相关资源
      最近更新 更多