Soren has taught me yesterday that some of the bugs I encountered have been properly disinsected by Microsoft, so other than the workarounds I suggested, there is an option to apply the hotfix and forget about that one.
Today, I’ll explain a not so critical bug, as the one yesterday, but depending on what exactly you do with Web services, it may be more than just a nuisance.
Hello, bug #3: accessing WSDL without database-wide permissions.
This one is very simple to repeat, and you don’t need any coding. You simply need to have a Windows login which only has roles assigned for a single company.
Follow these steps:
- Add a Windows login to your NAV database, assign it to SUPER role, and specify company for that role. For example:
- Synchronize the login, if necessary.
- Publish a page as a Web service, say 21 Customer Card, call it whatever
- Restart the NST (the Web services part).
- Open the browser as the user you defined in step 1.
- Navigate to the WSDL of the Web service defined in step 3, e.g. http://localhost:7047/DynamicsNAV/WS/Page/Customer
At this point, this is what the server returns: “The remote server returned an error: (500) Internal Server Error.”
Now do a funny thing. Access the same Web service, but as a user who has database-wide SUPER role (SUPER without a company name specified).
Now you get WSDL as expected.
Now repeat the same as the user with only company-level SUPER role. Guess what – no more errors. The server happily returns the WSDL.
So, a one-sentence description of symptoms is this: a user with only company-level access cannot read WSDL of a Web service unless a user with database-wide SUPER access has previously read the WSDL of the same service.
I can’t tell exactly what’s happening under the hood, but I imagine it’s some security glitch which prevents the user to read WSDL unless the user has database-wide SUPER access. If a database-wide SUPERman has already read the WSDL, it seems to be cached, and returned to anybody else from cache, regardless of their security permission.
So, it may be that accessing WSDL without database-wide SUPER role is prohibited by design, in which case WSDL shouldn’t be returned from cache. Or it may be that anybody should read the WSDL as long as they have proper access to the underlying object(s), in which case there is a bug in returning the WSDL back to the user.
In any case, not good.
Well, there is none I could identify. The only thing you can do is access WSDL as a superman, then consuming the service as whoever.
However… (there must be a however)
What if you had a generic application (and I know of at least three of such) which must access WSDL in runtime, and that WSDL might be accessed by a mere mortal?
There are several possible options:
- If objects are not expected to change, access WSDL once for each needed service during setup, and cache the WSDL description.
- If objects are expected to change, create a Windows service which runs as a superman, and accesses WSDL on behalf of mortals.
- As an alternative to above, you may store credentials of a superman (of course, you should use some strong encryption here, e.g. the one Windows uses for storing credentials of Windows services), then if reading of the WSDL fails for the error seen earlier, you retry as superman and see if it works.
I understand this might not be a big problem for most of Web services applications, primarily those that are custom-built for a single customer. But if you have any ISV application which is not specific to an installation, but can run under many different installations of NAV, then this problem might hurt you a bit, in which case I hope you read this post before you actually deploy the application to hundreds of customers.
If you have some thoughts about this problem, or are aware of a hotfix which solves it, please contribute.