Friday, March 3, 2017

Using Azure Key Vault to Store Configuration Data

There’s lot of ways to store things like username, passwords, urls, etc. for use in CRM code. I’ll be comparing some of those methods in a future blog post, but the more common approaches usually lack 2 things.

First, if you place a value inside some CRM construct and that data changes then you need to track it down in each and every environment and make updates. Maybe doesn’t sound so bad if you’ve only got a couple environments and a little bit of code but as you expand into larger organizations with multiple orgs for Dev, Test, QA, Training, Production, etc. and you start having multiple developers each take their own approach to handling this data, well you can see where this suddenly gets hard to manage.

The second thing is that these usernames and password stored in CRM really aren’t secure. The data isn’t encrypted unless you’re handling it yourself. Sure you can control which users have read access to the plug-in configurations or custom entity records but that probably won’t satisfy that guy from IT security.

One possible solution is to use the Azure Key Vault to store this sensitive information. You can read the finer points for yourself but these are some of the key takeaways:
  • Encrypted storage
  • Centralized management – keep track of all your configuration data in 1 place
  • Logging of key use
  • Simple REST API
Of course there’s some not so good points:
  • Some performance hit – need to make requests outside CRM to get the data
  • Can only retrieve 1 key at a time (unless you’re tricky and combine values)
  • Cost – $.03 per 10,000 operations, not free but not terribly expensive
  • Still need to manage some configuration values inside CRM in order to retrieve data
Still interested?

Getting Set Up

Create a Key Vault in Azure – should be pretty self-explanatory when you click through the portal

image

Create a Secret in the Key Vault

image

Register an application with Azure AD in order to get a Client Id & Client Secret – no different than generating values for CRM Web API use

image

image

Authorize the application – in your Azure AD application you’ll need to give it delegated permissions to Azure Key Vault

image

Allow application access to your secret by created an Access Policy – choose the application you registered as the Principal and give it Secret – Get Access, if you plan on trying to retrieve a Secret based on the name as you’ll see later on, also assign Secret - List Access

SNAGHTML21dd96db

In your Secret, grab the Url as you’ll need it to access it later

image

Finally back in Azure AD under Properties, get your Directory (Tenant) Id as this is also needed later

image

Retrieving A Key Vault Secret In Code (Part 1) Get The Access Token

  1. Use the Client Id, Client Secret, and Tenant Id to request the access token needed for the Key Vault requests
  2. Deserialize the JSON response and extract the token


Retrieving A Key Vault Secret In Code (Part 2) Retrieve A Secret By Url

Earlier in the set up steps you were able to grab a url corresponding to the specific version of the Secret you stored. In cases where you don’t plan on changing the value (revising), using the url should be OK.
  1. Use the url of the Secret and make a HTTP GET request including the access token in the authentication header
  2. Make sure you’re also including the API version at the end of the url
  3. Deserialize the JSON response and extract the value


Retrieving A Key Vault Secret In Code (Part 3) Retrieve A Secret By Name

The problem with using a url is that if you ever want to change the Secret value, you’ll need to make a new version, which in turn creates a new url. I’m sure being able to maintain versions is helpful in many cases but if it’s something like a password, then not so much. The Key Vault API doesn’t have any type of query functionality but it does allow retrieving all versions of a given Secret. So what do we do when a Secret changes and we don’t want to go through CRM environments and update urls? The Key Vault API does provide a means to retrieve all versions of a Secret based on the name. We can do this and then determine which is the most recent, enabled version and use it to retrieve the current value. Admittedly this ends up being at least 3 requests to get the actual value but I guess it’s a small price to pay for security and convenience.
  1. Use the name of the Secret and make a HTTP GET request for the versions including the access token in the authentication header
  2. Max of 25 versions are returned so paging may be required
  3. Deserialize the results and determine which is the most recently created that is also enabled
  4. Use the “id” property (which is the Secret url) to retrieve the Secret value
  5. Deserialize the JSON response and extract the value


In conclusion, this might not be the best solution when performance is your primary concern but it you’re looking for security and manageability then this might be worth taking a look at.

You can download the complete sample here:
https://github.com/jlattimer/CrmAzureKeyVaultExample

Wednesday, January 4, 2017

Show SharePoint Documents on the Main Form

Here’s an easy way to embed the SharePoint document window you’d normally get by navigating to “Documents” under related records, which includes all the native functionality like search, upload,
This might fall under the area of semi/not supported but if it happens to break one day you won’t have invested too much.

You’ll need to create an iFrame for the SharePoint content, probably within it’s own tab. Remember what you name the iFrame as you’ll need to modify with that value.

When configuring the iFrame...

On the General tab:
  • Restrict cross-frame scripting… to Unchecked
On the Formatting tab:
  • Number of Rows to 34
  • Scrolling to Never
  • Display Border to Unchecked
You could set the rows to a lower number, you’d just end up with a scrollbar despite the never scroll setting.

Take this code and update the iFrame name and add it to the form. Call SetDocumentFrame during the form’s OnLoad event.

If you’re doing this, you might also consider turning on the option to auto-create SharePoint folders. Otherwise people are going to be getting prompted. You can find this under:

Settings –> Document Management –> Document Management Settings and then it’s on the 2nd page.

With any luck, you’ll end up with something like this:



Friday, December 30, 2016

New Tool - CRM Code Editor

If you’ve ever tried to make a quick change to some JavaScript code inside CRM you’ve probably come to the conclusion that the experience isn’t so great, in fact it’s terrible. Not being able to tab to indent code alone drives me nuts. Of course you can’t blame the product as it wasn’t designed to be an IDE and all the development money goes into things like editable grids and such. If you keep up on some of the news on the developer front you’ve probably heard of Visual Studio Code, Microsoft’s newish IDE which lets you edit a huge variety of code and runs on Windows, Linux, & Mac. The reason they can be able to support versions for multiple different operating systems is that it’s ultimately built on HTML & JavaScript which runs anywhere. I stumbled across a reference to the Monaco Editor which happens to be what VS Code is built on. If you follow the link you’ll see the editor running in your browser. And as it turns out, all the code is available on GitHub, so I decided to try and incorporate it into a CRM solution because it didn’t look like it would be all that hard. So in the the tradition of generically my named solutions I’ve created the CRM Code Editor.

For those that care, this was built using AngularJS and TypeScript.

To display the  web resources to edit I built my own grid to list the items. Remembering that natively finding a web resource is also difficult, I added the ability to filter by type, filter by managed/unmanaged and search on the name fields. At the grid level I also added some buttons to quickly:
  • Delete
  • Copy a link to the file
  • Copy a script tag (which in hindsight shouldn’t be available for non-JS files)
  • Open the native dependency window



As you would expect the editing experience is top notch now that we have a real editor. We no longer have to worry about tabbing out the code, it actually indents! There are the obvious things like syntax highlighting, intellisense, code folding, formatting code, etc. If you right-click inside the editor you’ll see a similar window & command palette like in VS Code which lets you do all kinds of things. Since CRM only supports a finite number of files types, I’ve enabled editing of JS, HTML, CSS, and XML files. FYI - if someone figures out a way to transpile TypeScript in a browser let me know as I’ll add that in as well.



I also enabled the diff. editor so you can easily compare the published version of a file to the working copy.



A few more features I added on top of everything else:
  • Save/Save As/Save & Publish
  • Copy code
  • Drag/drop files into the editor to upload/edit
  • Code snippets
If you follow my blog you probably saw that I created an extension for VS Code which contains code snippets for the entire CRM JavaScript SDK. I took all those and included them in this editor. You can find a full list of what’s available on that project’s site. For the most part if you start typing part of a known function like “getValue” you’ll be prompted with some options to choose from.



This solution probably isn’t for the full-time developer as I would expect they are already using a desktop based editor with source control integration to do all their work but this might be of use for those that aren’t or something you can keep installed in a sandbox to play around with and test things out easily.

Checkout the project on GitHub:

 https://github.com/jlattimer/CRMCodeEditor

For 2015 & 2016 use the v2.0.0.0 release
For 2011 & 2013 use the v1.0.0.0 release

https://github.com/jlattimer/CRMCodeEditor/releases

Friday, December 9, 2016

CRM REST Builder v2.5.0.0

New in this release:
  • Added 8.2 endpoint
  • Changed functionality to reload CSDL when endpoint changes to ensure metadata is correct
  • Added 8.2 option to return full entity on create & update
  • Added option to retrieve, update, and delete via alternate keys
  • Added header options for upsert (prevent create & prevent update)
  • Added ability to optionally select non-required parameters for actions & functions
Checkout the project on GitHub:

https://github.com/jlattimer/CRMRESTBuilder

For 2015 & 2016 use the v2.5.0.0 release
For 2011 & 2013 use the v1.5.0.0 release

https://github.com/jlattimer/CRMRESTBuilder/releases

Monday, October 31, 2016

CRM REST Builder 2.4.0.0

Long overdue but here’s an update I’ve been working on for awhile.
  • Added support for Web API actions & functions
  • Added Web API endpoint selection
  • Added Web API filtering on related records
  • Added Retrieve via odata.nextlink
  • Enhanced formatting of code output
  • Added format code option for code editor & FetchXML queries
  • Set exception alerts to Xrm.Utility.alertDialog when >= 6.0
  • Added button to launch from application ribbon to open full screen
  • Fixed handling of multiple Prefer headers
  • Misc. bug fixes, like the one where it was generating the wrong code for lookups
  • Moved project hosting to GitHub

Web API Actions and Functions
You’ll notice the buttons don’t light up immediately. In order to determine which actions and functions (including custom actions) are available in your org., we need to download and parse the metadata/CSDL (https://org/api/data/v8.1/$metadata) which happens to be quite large. This happens in the background so it won’t hold you up if you’re wanting to use other functionality.

Some actions and functions take complex objects (entities / entity collections) as parameters. Due to the complexity I didn’t want to try and tackle building one of those complex objects inside building the parameters for the action/function so instead in the parameter lit you’ll see something like this instead of fields to enter actual data:
  • entity logical name Entity
  • (Variable Types) Entity
  • Collection (entity logical name)
  • Collection ((Variable Types))
In these cases the parameter is an entity of a specific type, an entity which could be of variable types (think adding an account, contact, or lead to a marketing list), a collection of a specific type of entity, or a collection of variable types of entities. The generated code will provide the base to set the entity as the parameter (to to a collection) but for this version you’ll need to set the entity id and name (for variable types). This implies that the associated entity is already created, you could also insert code to create the associated record on the fly like if you are using WinOpportunity. You could insert the object code for a new opportunityclose entity and send that as the parameter to handle everything in one transaction. 

Web API RetrieveMultiple with Related Records
When using an ‘expand’ operation when querying a group of records you’ll notice the collection of child records for each parent record being retrieved is empty. This is by design. The max amount of records able to be retrieved by a query is 5,000, then they when you figure in a potential 5,000 child records for each of the 5,000 parent records you’d end up with a result set containing 25,000,000 records which just isn’t practical. So instead you’ll see returned a url for a standard Retrieve request for each of the sets of child records (relationship_name@odata.nextlink) that would need to be executed for each set of records. Make things easier and speed things up I’ve added the ability to generate code for these requests specifically.

Checkout the project on GitHub:

https://github.com/jlattimer/CRMRESTBuilder

For 2015 & 2016 use the v2.4.0.0 release
For 2011 & 2013 use the v.1.4.0.0 release

https://github.com/jlattimer/CRMRESTBuilder/releases