Adventures With Dynamically Cloaked ArcObjects
I ran into an interesting issue this week while working on Geocortex Optimizer. An integral part of Optimizer is a component we're calling Geocortex Agent which is an environment we created to host our Optimizer modules. Each module running under Geocortex Agent should be able to run under its own set of credentials, similar to a Windows service. Given that Windows has a good API to support thread-level impersonation I thought this would be a straight-forward feature to implement. I found a nice impersonation class that hid a lot of the complexities and as usual, thought I was done just a little too soon.
I wrote a Windows console application and tried to connect to an ArcGIS server from an impersonated thread and was immediately shut down when an E_ACCESSDENIED exception, thrown when I called GISServerConnection.Connect. I did some further experiments and discovered that the credentials of the original host process were being used for authentication instead of the credentials of the impersonating thread. After some head scratching and a few conversations with my co-workers, I decided that the most likely reason for this behavior was because ArcObjects and ArcGIS server were using DCOM for inter-process communication and DCOM used process tokens instead of thread tokens when performing authentication. I came across a note describing how clients making calls via DCOM must call CoInitializeSecurity and enable Dynamic Cloaking if they would like DCOM to use thread tokens by default. This worked like a charm. Thanks Dave!
The moral of my story is simple. Programming security is never as simple as you'd like. When undertaking any tasks where security is involved, be prepared to spend a few extra days to do research, experiments and a few extra dollars for Americanos as you consider your options when diagnosing security issues.