ServiceClient - Constructor useUniqueInstance, Clone, CallerId, WhoAmI #269
-
What is the intended use of the I've been getting some strange permission errors that indicate that perhaps the CallerID property isn't being cleared between instances with this set to true. (It's also possible it's a bug in my code, but I think it's ok). I'm trying to avoid the startup delay of the "whoami" call each time (is that really required?), but definitely need separate environments and users to be separate. Some background: My use case is running as close to unmodified as possible plugin code in an Azure Function, so I've created an implementation of |
Beta Was this translation helpful? Give feedback.
Replies: 8 comments 2 replies
-
Under further investigation, even when I put a clearly incorrect value in immediately after construction and
|
Beta Was this translation helpful? Give feedback.
-
So there are a few things going on here. First lets talk about UseUniqueInstance Generally, we recommend the use of .clone for creating distinct connections vs going though the whole new leg if your talking to the same instance. so in your case, keep a copy of the ServiceClient in memory and use .clone for each request vs creating a new connection ( this is actually pretty close to how the organizationservicefactory does this in Plugins BTW ) Caller ID is the ID of the System user in Dataverse, which I believe your aware of. The WhoAmI call your seeing is done to validate the connection is alive and working, it's used because its an extremely lightweight call on the server ( no disk used as all ) and causes the server host to load its organization cache, allowing subsequent calls to be much faster. |
Beta Was this translation helpful? Give feedback.
-
Are you saying I need to make a login() call off some kind before it will take effect? I'm used to the WebAPI where it's just a header added to each request. I was expecting that if I create a new instance of ServiceClient, set the CallerID property something bogus then execute a request - eg. Retrieve, it should fail as that bogus user doesn't have permissions to the entity (as the bogus user doesn't have any permissions as they don't exist. |
Beta Was this translation helpful? Give feedback.
-
It still takes 100ms+ in network latency etc. that's not needed if a. the server is already warm, from eg. other instances of my code. b. the first request is always immediately following construction Even if the server responds instantly the fixed overheads (TCP congestion windows etc) and the speed of light will hurt us. |
Beta Was this translation helpful? Give feedback.
-
Is there any chance of an explicit connection pool concept being introduced? Otherwise each consumer will need to implement their own and pray they get the calculation of the key correct to not accidentally cross contaminate between users/environments. Getting the expiry/connection closure policy right is tough too. Alternative, something closer to ADO.Net where instead of blocking, a new connection is created (up to a limit, which I guess could be influenced by the server's concurrency hint). |
Beta Was this translation helpful? Give feedback.
-
Ps. Thanks so much for the detailed responses! |
Beta Was this translation helpful? Give feedback.
-
Regarding Caller ID and the web API. if your passing AAD ObjectId to CallerId, the API will ignore it as it does not match a known user and it will use the connection user to process the request. Regarding WhoAmI, Regarding Connection pools and such. That said, if you think there will high enough volume to warrant a connection pool process, there are many things to consider and test for. Given your line of questioning, and that your asking about impersonation; I am making the assumption that your not using on behalf of authentication flows for your asp.net site. There are a number of other things to think though, but w/out understanding your site, and its purpose as well as expected volume's I cannot guide much beyond that. As a general rule though, cloning seems work for most sites. |
Beta Was this translation helpful? Give feedback.
-
It is once the connection is completed (The constructor returns)
The client properties predate the WebAPI headers :).. But, yes I agree we can add to the comments to correlate. Regarding Clone,
No, that is still possible by extensive create and delete of clients.. Its harder to do these days but it is possible under high load.
Correct, we are not exposing the wire protocol or provide access to it.. We use a number of different protocols, connection processes and in the future entirely different protocols . We hide this from you to insulate you from these changes as we make them. |
Beta Was this translation helpful? Give feedback.
Regarding Caller ID and the web API.
You can only send that after the call has been authenticated, in the case of the webAPI via Postman or some other client, your doing the JWT authentication flow and attaching it to the Authorize header when you talk to the WebAPI, coupled with the CallerID you achieve impersonation for that request.
In the Dataverse ServiceClient, assuming your not providing your own authentication handler, the client establishes the connection and does the first WhoAmI as the connecting user. At which point you have a ServiceClient you can set a Caller ID on.
See this article.. and note that there are 2 different properties..
CallerObjectId and MSCRMCallerId.
CallerOb…