Dynamics NAV Web Service Call with C# succeeds after 401 errors

孤者浪人 提交于 2021-01-29 09:13:20

问题


I'm experiencing some odd behaviour (meaning I don't understand what's happening) and I'd like some help fixing it if possible.

We have some Dynamics 365 NAV Business Central web services exposed an secure with an SSL ceritificate, which we're accessing using some standard C# code.

We've added the SOAP proxy to an ASP .NET Webforms application and this is all working as expected.

We then declare an instance of the web service, set the credentials using a new NetworkCredential instance, and set the web service to use PreAuthenticate, then call the method on our service.

public static bool CheckServiceStatus()
{
    bool returnValue = false;
    try
    {
        svcWebServiceServer webService = new svcWebServiceServer();
        webService.Credentials = new NetworkCredential(Globals.WebServiceUsername, Globals.WebServicePassword, Globals.WebServiceDomain);
        webService.PreAuthenticate = true;
        webService.FncServiceStatus(ref returnValue);
    }
    catch (Exception ex)
    {
        LoggingFunctions.WriteMessageToDisk("CheckServiceStatus error : " + ex.Message);
    }
    return returnValue;
}

When we look at the logs for this in Fiddler, we se that the service is called twice. The first time the call is made, we get a 401 error which responds telling us we must use NTLM, the second call is then made with a longer NTLM key and the call succeeds and we get our data...

First attempt...

Second attempt...

Can anyone tell me how to make the web service call so it authenticates first time? The 401s are being picked up as a DDOS style attack and then traffic is being blocked.

I have tried changing the way the credentials are passed, but this has made no difference...

public static bool CheckServiceStatus()
{
    bool returnValue = false;
    try
    {
        svcWebServiceServer webService = new svcWebServiceServer();
        CredentialCache credCache = new CredentialCache();
        credCache.Add(new Uri(webService.Url), "NTLM", new NetworkCredential(Globals.WebServiceUsername, Globals.WebServicePassword, Globals.WebServiceDomain));
        webService.Credentials = credCache;
        webService.PreAuthenticate = true;
        webService.FncServiceStatus(ref returnValue);
    }
    catch (Exception ex)
    {
        LoggingFunctions.WriteMessageToDisk("CheckServiceStatus error : " + ex.Message);
    }
    return returnValue;
}

回答1:


As per this article - https://docs.microsoft.com/en-gb/archive/blogs/chiranth/ntlm-want-to-know-how-it-works - NTLM works in a challenge response manner.

The first time the web service is called (even if you specify NTLM in a credentialCache object), it seems as though the first request is sent anonymously.

The server then responds with a 401, and some WWW-Authenticate headers specifying that the service requires authentication details via NTLM. This is the first 401.

The client (C# application) then sends a new request that includes the NTLM header which includes an encoded value representing the Username, computername and domain.

The server passes the request on to the authenticating server which generates a challenge and this is sent back to the client, in another 401 response. This is the second 401.

Once the challenge is received by the client, it calculates a hash value based on the challenge and the password, which is sent back to the web service. The authenticating server compares this hash with its own hash, and - so long as the credentials are correct - passes authentication, and a 200 response is returned, along with the results of the web service call the client made initially.

When we add PreAuthenticate = true to our code, we simply pass the NTLM username, computername and domain up front, bypassing the first step. This reduces the number of 401s from 2 to 1.

I do not claim to be an expert in the field of authentication, but after reading the page linked above and carrying out a number of tests, this is what we have found. If anyone would like to comment/correct me, please feel free.

For completeness, we have started to investigate the "UserName" authentication method in the Dynamics 265 setup to access Dynamics NAV 2018 web services, which pass this authentication to the control to Dynamics NAV 365, which means we get no 401s. However, we are now unable to access the webservices in a browser as this uses Digest, and we seem to be unable to authenticate with the browser, and get 400 errors.



来源:https://stackoverflow.com/questions/65201072/dynamics-nav-web-service-call-with-c-sharp-succeeds-after-401-errors

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!