alexandru-cernatescu
alexandru-cernatescu

Reputation: 21

The HTTP request is unauthorized with client authentication scheme 'Anonymous' Dynamics NAV

I have an issue regarding an .net core app (3.1) trying to consume a WS (SOAP) from a Dynamics Nav Server. (on-premise). When I'm in debugging mode everything works fine, but when I deployed the app to local IIS server I keep getting "The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'oRswGaADCgEAoxIEEAEA=,Negotiate'."

Client initialization

private async Task<TXSiteUser_PortClient> GetInstanceAsync()
{
            EndpointAddress endpointAddress = new EndpointAddress(serviceUrl);
            BasicHttpBinding basicHttpBinding = new BasicHttpBinding()
            {
                MaxReceivedMessageSize = int.MaxValue,
                MaxBufferSize = int.MaxValue,
                OpenTimeout = TimeSpan.MaxValue,
                CloseTimeout = TimeSpan.MaxValue,
                ReceiveTimeout = TimeSpan.MaxValue,
                SendTimeout = TimeSpan.MaxValue
            };

            return await Task.Run(() => new TXSiteUser_PortClient(basicHttpBinding, endpointAddress));
        }

Example of call to a WS

var client = await GetInstanceAsync();

var user = await client.ReadAsync(new Read { Id = id });

await client.CloseAsync();

return user.TXSiteUser;

The Dynamics server has the credential type "Windows". And below is the web.config

<configuration>
  <location path="." inheritInChildApplications="false">
    <system.webServer>
      <handlers>
        <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
      </handlers>
      <aspNetCore processPath=".\ArtoilPortal.exe" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess" />
    </system.webServer>
  </location>
</configuration>

The weird thing is that when I'm in debugging mode and testing the endpoints from Swagger, everything works ok. Also, everytime I try to use postman I get a 401, no matter of Auth type (Basic,NTML). Also i've tried adding

basicHttpBinding.Security.Mode = BasicHttpSecurityMode.Transport;
basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
var username = _appSettings.NAVCredentials.UserName;
var password = _appSettings.NAVCredentials.Password;

and extended the PortClient method like this

        public TXSiteUser_PortClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress, string userName, string password) : 
                base(binding, remoteAddress)
        {

            this.ChannelFactory.Credentials.UserName.UserName = userName;
            this.ChannelFactory.Credentials.UserName.Password = password;
            ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
        }

with no luck

Upvotes: 1

Views: 2851

Answers (1)

alexandru-cernatescu
alexandru-cernatescu

Reputation: 21

managed to solve the errors. Firstly, the client initialization code was fixed by using "TransportCredentialOnly" instead of "Transport"

 basicHttpBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;

TransportCredentialOnly mode is used when there's no SSL configured for the SOAP services on Dynamics NAV server.

And the version of "PortClient" method that works for me looks like this:

public TXSiteUser_PortClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress, string userName, string password) : 
            base(binding, remoteAddress)
    {
        this.ClientCredentials.Windows.ClientCredential.UserName = userName;
        this.ClientCredentials.Windows.ClientCredential.Password = password;
        this.ClientCredentials.Windows.ClientCredential.Domain = "";
        ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
    }

In the original post I was setting

 this.ChannelFactory.Credentials.UserName.UserName = userName;

Where it should've been

 this.ClientCredentials.Windows.ClientCredential.UserName = userName;

Hopefully this will help somebody at some point

Upvotes: 1

Related Questions