29. März 2017
Using AD Accounts in containerized NAV and what I learned on the way
Since the first tries to get NAV in a Windows Container up and running I had the problem that compiling table structure changes didn’t work. The dev environment tried to connect to the NAV Server instance to start the sync but always returned with an error message that the Management Service wasn’t available. Here is how we solved this, again with a lot of help by Jakub Vaňák:
Find the reason: maybe networking or the Service not starting?
From the very beginning, Jakub suspected that we needed to use AD accounts (as we are in Windows Containers, actually we needed to use gMSAs, read a quick intro here). To be honest, I personally was completely wrong by thinking that maybe the Management Service was blocked on some network issue, didn’t come up or at least not fully, although the event log looked fine. To verify or falsify my suspicion I built a small script along the lines of this. It clearly showed that the Service was up and available.
Find the reason: ask the application!
For that I enabled tracing on the WCF services that are part of the NAV Server. How to do that is documented quite well here and it basically comes down to adding something like the following in the Microsoft.Dynamics.Nav.Server.exe.config in the system.diagnostics section:
<source name="System.ServiceModel" switchValue="All">
<add name="xml" />
<source name="System.IdentityModel" switchValue="All">
<add name="xml" />
<add name="xml" type="System.Diagnostics.XmlWriterTraceListener" initializeData="c:\log\Traces.svclog" />
After that I copied the resulting trace to the host and opened it with the Service Trace Viewer Tool.
This nice tool allowed me to easily identify the problem: System.ServiceModel.Security.SecurityNegotiationException: The server has rejected the client credentials. —> System.Security.Authentication.InvalidCredentialException: The server has rejected the client credentials. —> System.ComponentModel.Win32Exception: The logon attempt failed
Ok, I wouldn’t have thought so, but obviously there seemed to be some kind of authentication even if only the dev environment asked the NAV Server instance to sync table changes. Which actually makes sense… I then wasted some time by trying to override the WCF Service configuration to not request authentication which also was doomed because I was able to kind of get there but then the dev env still tried to send the authentication info and the Service didn’t know how to respond. Therefore, I did what I should have done in the very beginning, I followed Jakub’s idea to use gMSAs.
Solve the problem
It turned out to be not that difficult: With the documentation here and Jakub pointing me to this gist it went quite well. You can currently find the result in the gMSA branch of Jakub’s GitHub repo but I think we’ll merge it to master soon. I just don’t like to have to use hostnames identical with the gMSAs which also means you need one gMSA for every container instance per host. As you can see in the gist the author Patrick Lang seems to think that setting correct SPNs could do the trick and I’ll try to work in that direction. Therefore again, this is to be continued…