Monday 18 December 2023

Dynamics 365 Finance and Operations: Non-Azure AD external user sign-in Deprecation March 2024

This post has moved to my new website, if not redirected automaticaly please click here: https://anthonyblake.github.io/d365/finance/sysadmin/2023/12/18/d365-external-user-deprecation.html 

From March 2024, Microsoft will begin restricting access to users of Dynamics 365 Finance and Operations to only allow users which exist in the same Azure Active Directory tenant. This is billed as having an impact on 3rd party tenant accounts which are not b2b onboarded, however there is a potential integration impact which I will cover later.

This will affect any users from external tenants which are not also configured as guests in the host tenant for the D365 environment. These are the users where, for example, your tenant is contoso.com, but the F&O environment contains users which authenticate against my3rdpartytenant.com. These will be accounts which you see in your Users form with their own tenant suffixed on the provider. 

Microsoft have provided a link with clear instructions on how to implement guest accounts in Entra here:

https://learn.microsoft.com/en-us/entra/external-id/what-is-b2b

If an account is already guest on the F&O tenant, I don't believe any further action will be required in March 2024 when this is implemented.

Potential integration impact

If you have integrations which require access to D365 F&O, you are likely to be implementing authentication via Azure app registrations, which link to a user for Authorisation in the System administration->Setup->Azure Active Directory applications form. 


In integration design, it is likely that the user assigned to the AAD app is not intended to be used for D365 login, so it may have been created in the users form and not necessarily imported from AAD/Entra as real users are. There is the potential (not tried, so not confirmed) that the upcoming changes to authentication could disable the account linked to the app registration and therefore, integrations would stop working.

The solution would be simple, to setup the linked D365 user ID in the Azure AAD tenant. 

If this turns out to be an issue for integrations will depend on how the deprecation is implemented. For integrations, these users are not used to authenticate, only to authorise by linking AAD client Ids to security roles, so there could be no action to take. It is possible this impact may go under the radar, so its one to look out for in March 2024.

The announcement of the deprecation is here: 

Removed or deprecated platform features - Finance & Operations | Dynamics 365 | Microsoft Learn

Friday 1 December 2023

Azure Logic Apps (Consumption): Create an Asynchronous API for Long Running Operations

This post has moved to my new website, if not redirected automaticaly please click here: https://anthonyblake.github.io/azure/logicapps/2023/12/01/async-logic-app.html 


Get the code for this demo on GitHub, including 1-click Azure deployment and postman collection for testing:


Background

An HTTP triggered logic app is a great tool for creating an API which performs a set of actions when called. When those actions involve interacting with other applications and waiting for processes to complete, the can become long running. An example could be loading a batch of data to a Dynamics 365 Finance recurring integration, which involves uploading, queuing, and polling the application for a result.

When adding a specific response to a logic app, by default, the HTTP trigger will run synchronously, where the caller waits for the logic app to complete before receiving a response. In a long running process scenario, we can design the logic app to run using an asynchronous pattern.

This is great in 2 specific scenarios:

  • You want a return a response body from your Logic App to the API caller, without locking up a the callers session waiting for the long running App to complete.
  • For a consumption app, you have a workflow which runs for over the timeout limit of 2 minutes.

When running asynchronously, the Azure Logic App will send back an initial HTTP 202: Accepted response to the caller app, indicating that the request has been received and it is being processed. It also returns a URL in the Location header which can be used to poll the Logic App until completed. This will continue to return a 202 while the Logic App is running, when completed it will return the response defined in the workflow, usually a 200: OK, along with any body information from the call.

Create an Asynchronous Logic App 

In Azure portal (because the example is a Consumption Logic App), create a new Logic App.


Add an HTTP request received trigger, on save the URL to trigger the logic app will be generated in the HTTP POST URL field.

Add a delay step to simulate the long running process. 


I went for a delay of 5 minutes, to prove that this Logic App remains responsive beyond the 2 minute consumption Logic App timeout, and to give me time to screenshot some responses.

Finally, add a response action. The status code I've chose for the example is 200 OK, and I've created a Json body containing a field called status, so we can see when the body is returned later.


The entire workflow should look like this.


At this point, running the workflow would return a timeout exception, because the response action would not be reached within the 2 minute timeout.

We need to modify the response to be Asynchronous. From the three dots menu on the Response step, click Settings.


The second option in Settings is Asynchronous Response. Toggle it to be ON.


Test the Workflow

The workflow is all set to return an Accepted response and be polled until complete. The best place to test it is in Postman.

In a new or existing collection, create a new HTTP post request using the URL generated when saving the HTTP request trigger in the Logic App earlier.

Hit the Send button. The response should be a 202 Accepted.



The location header in the 202 response contains the URL to poll for the status of the running logic app. If can be copied and pasted manually into a new GET request each time the logic app runs, or we can automate that using the Tests tab and an environment variable.

Create a new environment or modify an existing environment, and add the variable get_status_url;

To store the status URL from the location header, add the following code under the Tests tab of the initial request:

Copy and paste version:
pm.environment.set("get_status_uri"pm.response.headers.get("Location"));

Create a GET request, and for the URL use the environment variable get_status_url in double braces:


If the get request is called within the 5 minute delay, so while the Logic App is executing it's long running process, the response will continue to be a 202 Accepted, with a body containing the the status Running in the properties object.



Click send and poll the Logic App multiple times during the long running process. The response will remain a 202 Accepted until the Logic App completes, when a 200 OK will be returned, along with the body we defined in the Response step of the Logic App.


Done. An Asynchronous solution to allow Consumption Logic Apps to run for longer than 2 minutes, transferable to Standard Logic Apps to prevent caller threads being blocked, and potentially timed out, by long running processes.

Please leave a comment below if this has been useful - all feedback welcome.

Get the code for this demo on GitHub, including 1-click Azure deployment and postman collection for testing: