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

Viewed 725

Receiving the following error message regardless of basicHttpBinding or wsHttpBinding in .net core 3.1:

 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)

this is the code:

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();

i am not after a solution but some pointers on either what am i doing wrong here or what else should i try to figure out?

3 Answers

The type of binding and the sort of credential should be consistent with the server’s configuration.
I suggest you generate a client proxy to call the remote service.
https://docs.microsoft.com/en-us/dotnet/core/additional-tools/wcf-web-service-reference-guide
With this tool, we can generate a proxy and get a proper configuration corresponding with the server configuration. afterward, we can make an invocation to the service.

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

Since the tool also generates the service contract on the client-side, we could also change a way to call the remote service according to the service configuration generated in the Reference.cs file.

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);

All we should pay attention to is that the type of binding and the security type should be consistent with the one on the server. Therefore, the first important thing is that we should find out the server configuration and apply it on the client-side.
Feel free to let me know if the problem still exits.  

I would create a ChannelFactory rather than getting the channel factory from a client in case anything is cached by the client:

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

found out the reason for the error is because WCF service has WS Policies and two of those policies are not supported in .NET Core. One is sp:encryptedsecuritytoken and other is sp:trust

Related