.net 核心调用 wcf 服务 - SecurityAccessDeniedException:安全令牌无法通过身份验证或授权

.net core calling wcf service - SecurityAccessDeniedException: The security token could not be authenticated or authorized

无论 .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();

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

绑定的类型和凭证的种类要和服务器的配置保持一致
我建议你生成一个客户端代理来调用远程服务。
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);

我们需要注意的是绑定的类型和安全类型要和服务器上的保持一致。所以,首先要弄清楚服务端的配置,然后应用到客户端。
如果问题仍然存在,请随时告诉我。

如果客户端缓存了任何内容,我会创建一个 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