【问题标题】:.net core calling wcf service - SecurityAccessDeniedException: The security token could not be authenticated or authorized.net 核心调用 wcf 服务 - SecurityAccessDeniedException:无法对安全令牌进行身份验证或授权
【发布时间】:2020-03-25 07:38:39
【问题描述】:

在 .net core 3.1 中无论 basicHttpBinding 还是 wsHttpBinding 都收到以下错误消息:

 SecurityAccessDeniedException: The security token could not be authenticated or authorized
 System.ServiceModel.Channels.ServiceChannel.ThrowIfFaultUnderstood(Message reply, MessageFault fault, string action, MessageVersion version, FaultConverter faultConverter)
 System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ref ProxyRpc rpc)
 System.ServiceModel.Channels.ServiceChannel.EndCall(string action, object[] outs, IAsyncResult result)
 System.ServiceModel.Channels.ServiceChannelProxy+TaskCreator+<>c__DisplayClass1_0.<CreateGenericTask>b__0(IAsyncResult asyncResult)

这是代码:

var binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;  
var address = new System.ServiceModel.EndpointAddress("soapendpoint");
var client = new Client(binding, address);

var cf = client.ChannelFactory;
cf.Credentials.UserName.UserName = username;
cf.Credentials.UserName.Password = password;
var channel = cf.CreateChannel();

var response = channel.GetPatientAsync();

我不是在寻求解决方案,而是一些关于我在这里做错了什么或者我应该尝试找出什么的指针?

【问题讨论】:

    标签: .net wcf asp.net-core-3.1


    【解决方案1】:

    绑定的类型和凭证的种类要与服务器的配置一致。
    我建议你生成一个客户端代理来调用远程服务。
    https://docs.microsoft.com/en-us/dotnet/core/additional-tools/wcf-web-service-reference-guide
    使用此工具,我们可以生成代理并获得与服务器配置相对应的正确配置。之后,我们可以调用该服务。

    ServiceReference1.ServiceClient client = new ServiceReference1.ServiceClient();
                var result = client.TestAsync();
                Console.WriteLine(result.Result);
    

    由于该工具也在客户端生成服务契约,我们还可以根据Reference.cs文件中生成的服务配置更改调用远程服务的方式。

    BasicHttpBinding binding = new BasicHttpBinding();
                binding.Security.Mode = BasicHttpSecurityMode.None;
                Uri uri = new Uri("http://10.157.13.69:21011");
                ChannelFactory<IService> channelFactory = new ChannelFactory<IService>(binding, new EndpointAddress(uri));
                IService service = channelFactory.CreateChannel();
                var result1 = service.TestAsync();
                Console.WriteLine(result1.Result);
    

    需要注意的是绑定的类型和安全类型要和服务器上的一致。因此,首先重要的是我们应该找出服务器配置并将其应用到客户端。
    如果问题仍然存在,请随时告诉我。

    【讨论】:

    • 我已经生成了一个代理类,但是如何找到服务器上使用的绑定以及.net core/支持的绑定
    • 检查位于 ServiceReference1 命名空间中的 Reference.cs 文件。它包含代理类、服务契约、绑定类型。当我们实例化客户端代理时,会自动使用这些配置。
    • 它只需要一个 System.ServiceModel.Channels.Binding 的对象。 Reference.cs 文件中没有其他内容。
    • 有可能导致reference.cs文件为空。也就是Webhttpbinding创建的WCF服务默认不支持代理调用。该文件不会生成任何内容。带有 webhttpbinding 的服务是 Rest API。我们需要使用 HTTP 库发送 HTTP 请求,该请求通常附加 HTTP 动词和请求正文。详情请咨询您的服务提供商。
    • 发现错误的原因是因为 WCF 服务具有 WS 策略,而 .NET Core 不支持其中两个策略。一个是 sp:encryptedsecuritytoken,另一个是 sp:trust
    【解决方案2】:

    我会创建一个ChannelFactory,而不是从客户端获取通道工厂,以防客户端缓存任何内容:

    var channelFactory = new ChannelFactory<SoapInterfaceType>(binding, remoteAddress);
    channelFactory.Credentials.UserName.UserName = "";
    channelFactory.Credentials.UserName.Password = "";
    var channel = channelFactory.CreateChannel();
    

    【讨论】:

    • 发现错误的原因是因为 WCF 服务具有 WS 策略,而 .NET Core 不支持其中两个策略。一个是 sp:encryptedsecuritytoken,另一个是 sp:trust
    • @Baahubali 很好的发现。也许您想将其发布为您自己的答案,以便人们可以轻松找到它。
    • 是的,我还没有解决这个问题。我试图弄清楚如何手动编写一个满足.net核心内这些策略的类。这是我的问题:stackoverflow.com/questions/60970867/…
    【解决方案3】:

    发现错误的原因是因为 WCF 服务具有 WS 策略,而 .NET Core 不支持其中两个策略。一个是 sp:encryptedsecuritytoken,另一个是 sp:trust

    【讨论】:

      猜你喜欢
      • 2015-10-02
      • 1970-01-01
      • 1970-01-01
      • 2020-09-24
      • 2010-10-31
      • 1970-01-01
      • 2018-08-21
      • 1970-01-01
      • 2018-07-18
      相关资源
      最近更新 更多