I have written in the past about Extensible Data Security (XDS) in D365FO, it has been one of my most popular posts. I often get questions about it, but one that I get quite often is wanting to apply XDS based on the current user. The use case is something along the lines of:
- ‘I only want a user to see sales orders/vendors/customers they created’
- ‘Users should only see records where they are the approvers’
In both of these cases we need the XDS applied to go against the current user logged into the system.
The test scenario I am going to utilize today is that a user should only be able to interact with vendors that they have created themselves.
The first thing we need to do is set up our query, in this case because we are going to want to compare results against a user Id we need to use a data source table that contains user Id’s. The obvious answer here is the UserInfo table however I found that trying to utilize this table threw an error as X++ deemed this table to be a ‘kernel table’. So instead, I utilized the SysUserInfo table which also includes user Id’s.
Once we set the Data Source as the SysUserInfo, the next step is setting the Range to use. In this case we are going to use the currentUserId() method to obtain the user Id. One thing to note here is that you must surround this value with parenthesis. If you do not do this, the value will be interpreted as a string and will not resolve the user Id.
Also note here that this CreatedByQuery can be reused by other security policies as needed.
The next step is setting up the security policy, in this case we set the Query as the CreatedByQuery created in the previous step and create a Context String so we can apply this to a role later on. We also set the primary table to the SysUserInfo table and be sure to set the Operation field to AllOperations if you want this XDS to be applied to all Read, Update, Create, and Delete functions.
The final piece of setting up the security policy is setting the constrained table, in this case though we will actually create a constrained expression because there is no native table relation between the VendTable and the SysUserInfo table. In the value property, we actually put in the relation clause we want to use to join the tables. Note again that you need to surround this value with parenthesis.
So now we have our query and security policy created, the last piece is applying this XDS policy to a security role. In this case I created a custom role and set the Context String of the role to the Context String I set in the security policy. This means that any user assigned this role automatically gets the XDS policy assigned.
XDS Results for Current User Setup
The role my test user (user Id of ‘fastpath’) is assigned grants full control to all vendor master data, so without XDS applied we can see this user has full access to all vendors in the USSI legal entity.
This user has created only the ‘Test 123’ and ‘Test 456’ vendors within this legal entity:
Once we enable the XDS policy and reload the page, we can see this user can now only interact with those vendors that they have created:
I created a YouTube video of me going through the steps above, feel free to check it out here:
If you would like me to make more videos like this please let me know!
I hope this helps to show how powerful the XDS feature is and how it can be used to solve lots of different user requirements. As always, feel free to reach out with any questions.