1
votes

I have a Microsoft Dynamics CRM implementation (either 2010 or 2011 in not 100% sure). This CRM system needs to call our internal service framework services from plug ins.

In order to call the service framework we use an API with a login method that goes to an STS and gets a security token. This is per user to authenticate and get that users claims. The login call returns an IPrincipal object that we put on the Thread.CurrentPrincipal property and from then on we can call services with our framework and the user is authenticated for each call because of the principal on the executing thread.

In an asp.net website we usually log the user in and immediately go to the STS to get a token, then cache that token for the user in session because the login is not something we want to do every time we want to call a service.

How would I do this with a CRM plugin. Do I have access to a per user session store? I noticed IServiceProvider is passed in as a parameter, can I add services to this container and solve this problem in a service with a thread safe dictionary of some kind? I know very little about CRM development and Im even wondering if a plugin is the right way to do this?

3

3 Answers

2
votes

The plugin is created and cleaned on a regular basis, you wouldn't be able to store anything for any period of time (or at least store it and rely on it being there).

You could potentially store this in a custom entity though if that is something that is possible?

e.g. - Plugin is called for x event

  • Get CallingUser from Plugin

  • Search for MyCustomSTS entity for the User

  • See if Token exists and/or has expired

  • If you have the token - hooray

  • If not, run off and grab one

This may, of course, take longer than reauthenticating each time!

0
votes

Is the token you are fetching for individual users or for the service account?

Ideally you should write your plugin to be stateless.

Write a Plug-In

For improved performance, Microsoft Dynamics CRM caches plug-in instances. The plug-in's Execute method should be written to be stateless because the constructor is not called for every invocation of the plug-in. Also, multiple system threads could execute the plug-in at the same time. All per invocation state information is stored in the context, so you should not use global variables or attempt to store any data in member variables for use during the next plug-in invocation unless that data was obtained from the configuration parameter provided to the constructor. Changes to a plug-ins registration will cause the plug-in to be re-initialized.

If you are fetching a token for individual users you could save that in CRM somewhere but that approach has a number of problems as glosrob suggests. In this case its probably just best to authenticate every time.

If its for the service account, you could go against the recommendations of Microsoft and cache the token in memory. Logically as long as your write your code to be happy with randomly loosing and having to reacquire its token you should be okay.

0
votes

I agree with people who says that each time authentication is better solution, but if you need storage for tokens, you can create custom CRM entity and write logic which will work with tokens stored in CRM from plugins.