.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
无论 .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