MATLAB: How to obtain Azure AD tokens in MATLAB R2020b

MATLAB

I want to interact with services hosted on my company's Microsoft Azure environment. These services requires me to include an Azure AD token in the header when calling a RESTful service or I need to use the Azure AD token as the password when for example connecting to a MySQL or PostrgreSQL database. I can obtain these tokens through the Azure console (i.e. use "az login" followed by "az account get-access-token …") and once I have the token and paste it into MATLAB I can then indeed also successfully interact with the services which I want to work with from MATLAB (through functions like "webwrite", "database", etc.). My question is now though whether these tokens can be obtained inside MATLAB directly?

Best Answer

It is indeed possible to obtain these tokens inside MATLAB directly, depending on your exact use-case this may still involve pop-ups though in which you still do need to interactively login to your Azure account or in some cases the flow can be entirely non-interactively.
Prerequisites on the Azure end
For this to work, first of all you need an App registration in your Azure directory; you may already have one for the service which you want to interact with and you can then reuse this or you can register a new App specifically for MATLAB and grant it the correct API Permissions to interact with the actual Azure service(s) you want to interact with. Further, you now need to decide whether you want/can interact with your service on behalf of a specific user (which requires at least one interactive sign-in) or on behalf of the application itself (which can be entirely silently). In either case make sure your App is configured to support "Mobile and desktop applications" Authentication and:
1. If you will be acting on behalf of specific users make sure you add/enable the following Redirect URI:
https://login.microsoftonline.com/common/oauth2/nativeclient
2. If you will be interacting on behalf of the application itself, create a "Client secret" for MATLAB and note it down.
Obtaining the token in MATLAB
We will again be differentiating between obtaining a token for a user or for the application.
User Token
Obtaining a token for a user involves an interactive authentication flow in which you may need to interactively login in a browser window. And the easiest ways to complete this authentication flow is to make use of one of the MSAL libraries provided by Microsoft. We show two options here .NET based MSAL.NET and Java based MSAL4J.

.NET Based MSAL.NET (in MATLAB only supported on Windows)

1. First of all you will need the actual MSAL.NET libraries. You can download the latest NuGet package using the "Download package" link on the right on:
You can extract the downloaded package as a ZIP-file and then inside the "lib\net45" directory you should find "Microsoft.Identity.Client.dll" which should be compatible with MATLAB. Copy it somewhere where you can easily access it from MATLAB.
2. Load the downloaded Assembly in MATLAB using NET.addAssembly, this requires a full path to the Assembly, for example:
NET.addAssembly('c:\full\path\to\Microsoft.Identity.Client.dll')
Or if the Assembly is inside your current working directory inside MATLAB you can for example use:
NET.addAssembly(fullfile(pwd,'Microsoft.Identity.Client.dll'))
3. Now you can use this Assembly to create a PublicClientApplicationBuilder:
%% Fill in your Azure AD Tenant ID and the App ID of the App you

% created/work with for MATLAB

tenantId = '';
appId = '';
%% Then create an PublicClientApplicationBuilder

app = Microsoft.Identity.Client.PublicClientApplicationBuilder.Create(appId)...
.WithAuthority(Microsoft.Identity.Client.AzureCloudInstance.AzurePublic,tenantId)...
.WithRedirectUri('https://login.microsoftonline.com/common/oauth2/nativeclient')...
.Build();
4. Then you will need to define which scopes you want to request access for. Which scopes you will need to request access for depends on the services you want to interact with, consult the Azure documentation of the services you want to work with to learn more:
% Start with creating a list of Scopes

scopes = NET.createGeneric('System.Collections.Generic.List',{'System.String'});
% Add actual Scopes to them, for example

scopes.Add('https://graph.microsoft.com/.default')
5. Finally, actually show the dialog in which you can login and grant access for these scopes and obtain the returned token:
% Show the interactive dialog in which the user can login
tokenAcquirer = app.AcquireTokenInteractive(scopes);
result = tokenAcquirer.ExecuteAsync;
% Retrieve the returned token

token = char(result.Result.AccessToken);
You should now have the token you need in order to be able to interact with Azure services on behalf of the user who logged in in the interactive dialog.
 

Java Based MSAL4J (supported on all MATLAB platforms)

1. First of all you will need the MSAL4J libraries (and its dependencies). It does not appear that there is a direct download available of a package including all dependencies. Microsoft provides a Maven package though. See the following related article which shows how you can download a Maven package including all its dependencies for easy usage inside MATLAB:
2. Once you have obtained your self-contained JAR-file, add it to your static Java classpath in MATLAB. I.e. open javaclasspath.txt in your MATLAB preferences directory in the MATLAB Editor using:
edit(fullfile(prefdir,'javaclasspath.txt'))
Then add a line:
c:\full\path\to\your\msal4j-X.Y.Z-jar-with-dependencies.jar
Save the file and then restart MATLAB.
3. Now you can use the package to create a PublicClientApplicationBuilder:
%% Fill in your Azure AD Tenant ID and the App ID of the App you
% created/work with for MATLAB
tenantId = '';
appId = '';
%% Then create an PublicClientApplicationBuilder
app = com.microsoft.aad.msal4j.PublicClientApplication.builder(appId)...
.authority(['https://login.microsoftonline.com/' tenantId])...
.build();
4. Then you will need to define which scopes you want to request access for. Which scopes you will need to request access for depends on the services you want to interact with, consult the Azure documentation of the services you want to work with to learn more:
% Create an empty set

scopes = java.util.HashSet;
% Add the desired scopes to it one-by-one

scopes.add('https://graph.microsoft.com/.default');
5. Finally, actually show the system web browser in which you can login and grant access for these scopes and obtain the returned token:
params = com.microsoft.aad.msal4j.InteractiveRequestParameters.builder(java.net.URI('http://localhost'))...
.scopes(scopes).build();
tokenAcquirer = app.acquireToken(params);
result = tokenAcquirer.join;
token = char(result.accessToken);
You should now have the token you need in order to be able to interact with Azure services on behalf of the user who logged in in the web browser.
 
Application Token
For this approach we present three options, a simple RESTful call can suffice here to obtain the token which can easily be performed with MATLAB's "webwrite" function without any further dependencies on external libraries, but we also show the MSAL.NET and MSAL4J approaches.

RESTful approach (available in MATLAB on all supported platforms without any third-party libraries)

This really just needs one relatively simple call to "webwrite":
%% Fill in your Azure AD Tenant ID, the App ID and Client Secret


tenantId = '';
appId = '';
clientSecret = '';
%% Perform request using webwrite
response = webwrite(['https://login.microsoftonline.com/' tenantId '/oauth2/v2.0/token'],...
'client_id',appId,...
'client_secret',clientSecret,...
'scope','https://graph.microsoft.com/.default',...
'grant_type','client_credentials');
token = response.access_token;
Where you may only have to change the scope which you want to request access to.

.NET Based MSAL.NET (in MATLAB only supported on Windows)

1-2. The first two steps are exactly the same as for the User Based MSAL.NET approach, see above.
3. Now you can use this Assembly to create a PublicClientApplicationBuilder WithClientSecret:
%% Fill in your Azure AD Tenant ID, the App ID and Client Secret
tenantId = '';
appId = '';
clientSecret = '';
%% Then create an PublicClientApplicationBuilder - WithClientSecret
app = Microsoft.Identity.Client.ConfidentialClientApplicationBuilder.Create(appId)...
.WithAuthority(Microsoft.Identity.Client.AzureCloudInstance.AzurePublic,tenantId)...
.WithClientSecret(clientSecret)...
.Build();
4. Defining the lists of scopes is the same again as in the User based approach:
% Start with creating a list of Scopes
scopes = NET.createGeneric('System.Collections.Generic.List',{'System.String'});
% Add actual Scopes to them, for example
scopes.Add('https://graph.microsoft.com/.default')
5. Obtain the token using a non-interactive call:
% Obtain the token, this worfklow is entirely non-interactive
tokenAcquirer = app.AcquireTokenForClient(scopes);
result = tokenAcquirer.ExecuteAsync;
% Retrieve the returned token
token = char(result.Result.AccessToken);
You should now have the token which allows you to interact with your services on behalf of the application.

Java Based MSAL4J (supported on all MATLAB platforms)

1-2. The first two steps are exactly the same as for the User based MSAL4J approach, see above.
3. Now you can use the package to create a ConfidentialClientApplication:
%% Fill in your Azure AD Tenant ID, the App ID and Client Secret
tenantId = '';
appId = '';
clientSecret = '';
%% Create the ConfidentialClientApplication
clientCred = com.microsoft.aad.msal4j.ClientCredentialFactory.createFromSecret(clientSecret);
app = com.microsoft.aad.msal4j.ConfidentialClientApplication.builder(appId,clientCred)...
.authority(['https://login.microsoftonline.com/' tenantId])...
.build();
4. Defining the scopes is exactly the same as in the User approach:
% Create an empty set
scopes = java.util.HashSet;
% Add the desired scopes to it one-by-one
scopes.add('https://graph.microsoft.com/.default');
5. Now actually obtain the token using a completely non-interactive flow:
params = com.microsoft.aad.msal4j.ClientCredentialParameters.builder(scopes).build;
tokenAcquirer = app.acquireToken(params);
result = tokenAcquirer.join;
token = char(result.accessToken);
You should now have a token which allows you to interact with your Azure services on behalf of the application.