Question

I am trying to access a Dynamics NAV 2013 R2 web service from Java. The web service is running and when I enter the URL in the Internet Explorer, I can see the WSDL but first I am prompted for Username and Password. On Wireshark I can see that it uses authentication based on NTLM. Sofar I was only able to open the WSDL from Internet Explorer, when I open it on Firefox, it give me a blank page and no error.

What I am trying to do is to access the Web Service from Java using the wsimport tool, but I am unable to authenticate. I have already created a folder in ~/.metro/auth and put the following line in there:

http://userfoobar:passforbar@192.168.0.170:7047//DynamicsNAV71/WS/CRONUS%20AG/Page/PageWithCapitalization

and I am trying to access the web page with:

wsimport -d generated -s sources http://@192.168.0.170:7047/DynamicsNAV71/WS/CRONUS%20AG/Page/PageWithCapitalization

I always get the error:

[ERROR] Server returned HTTP response code: 401 for URL: http://@192.168.0.170:7047/DynamicsNAV71/WS/CRONUS%20AG/Page/PageWithCapitalization,  "http://@192.168.0.170:7047/DynamicsNAV71/WS/CRONUS%20AG/Page/PageWithCapitalization" needs authorization, please provide authorization file with read access at /home/user/.metro/auth or use -Xauthfile to give the authorization file and on each line provide authorization information using this format : http[s]://user:password@host:port//<url-path>

I have tried this both from Linux and the Windows 7 machine which runs the NAV Webservice. Do I have to perform any additional configuration in NAV? Are there any special tricks to get this to work?

Was it helpful?

Solution

By default Nav uses Windows Active Directory authorization. I'm not sure what wsimport do in java but credentials provided in url unlikely to work. You need to go through negotiation procedure to authorize with server or change authorization type in Nav Server Administration snap-in on server (or in configuration file).

See here about credential types and here is how to configure server. Also see usefull post in Freddy's blog on how to connect to Nav from Java (I believe its still relevant though it's for Nav 2009).

soapUI can handle NTLM authorization type so you can see all requests and responses through negotiation process in it's logs.

OTHER TIPS

You can use either NTLM authentication or Basic authentication to access a NAV web service. You can use Postman, curl or any of the popular programming languages.

Use NTLM authentication when NAV is using the Windows credential type. The username and password belong to the Windows user added in NAV. The user must be enabled in NAV. The username and password must be valid on the windows machine, that is, someone can login on the computer using them. Ensure that the checkbox Use NTLM Authentication is checked in NAV Administration. Postman has beta support for NTLM authentication.

Use Basic authentication when NAV is using NavUserPassword credential type. The user must exist in NAV and have a username and password. To supply the fields when making a request, Base64 encode the username and password combination, that is, base64 encode this: username:password. For example, if my username is jack and password is Jack@1234, the base64 encoded string I'll use is: amFjazpKYWNrQDEyMzQK . I've obtained it using below bash command:

echo 'jack:Jack@1234' | base64

Use the normal protocol for basic authentication to supply the authentication in the http request. See: https://learning.postman.com/docs/sending-requests/authorization/

Below is a guide on NTLM authentication using the httpntlm library in node.js. Another library you can use is axios-nltm.

For PHP developers, see this article on php ntlm authentication.

NTLM authentication allows a client to access a resource on the server by providing credentials for a Windows account that exists on the server.

So if the server has a user named GilbertS with a password Gilbert1000, you can send a request to the server by running the following javascript code:

const httpntlm = require('httpntlm');

const NAV_DimQuery = "http://junit:7148/BC140/ODataV4/Company('CronusCompany')/MyDimensionQuery";
httpntlm.get({
    url: NAV_DimQuery,
    username: 'GilbertS',
    password: 'Gilbert100',
    domain: 'JUNIT'
}, function(err, res) {
    if(err) {
        throw err;
    } 
    console.log(res);
});

Install the necessary library by entering the command: npm i httpntlm Note that other languages like PHP and Java have a similar library.

To get the Domain name, from the command prompt or terminal of the server, run: SET Look for the value of a key called USERDOMAIN. Note that the domain can be left blank if the server is a PC and not a dedicated Windows Server.

NAV / Business Central specific configurations

In NAV or Business Central Administration, there is a field in the General tab called Use NTLM Authentication ensure that it is checked (set to true). If you can not modify it from the NAV / BC Administration window, edit the CustomSettings.config file in path: C:\Program Files\Microsoft Dynamics 365 Business Central\140\Service.

Because we are using NTLM to authenticate, ensure that NAV / BC is configured to use Windows authentication. You do so by setting the Credential Type to Windows.

If the Credential Type is set to something else or you do not tick Use NTLM Authentication, you will get an error when sending the request saying something like the server does not allow NTLM.

Also, make sure that the Windows user you are using to access data in NAV / BC exists in the Users table in NAV / BC and that user is enabled.

If the NAV server is using NavUserPassword authentication, you can create another server instance that uses Windows authentication for the same database.

Finally, beware of a certain case where running the code makes the NAV Server to stop, I am still trying to figure out what causes this.

You can make inquiries in the comments in case there is something that is still making your requests to fail.

I've created two npm libraries to help with NAV / BC web service integration.

A library that makes creating a URL to send to the web service to consume Odata simple and declarative: https://www.npmjs.com/package/navodata

A client built on top of httpntlm library for accessing a web service using windows authentication. Provides error handling and use of promises: https://www.npmjs.com/package/navclient

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top