web
You’re offline. This is a read only version of the page.
close
Skip to main content

Announcements

News and Announcements icon
Community site session details

Community site session details

Session Id :
Power Platform Community / Forums / Power Apps / Call Azure function ap...
Power Apps
Answered

Call Azure function app from PCF using implicit flow

(0) ShareShare
ReportReport
Posted on by 16

Hi,

 

I have a azure function with Azure AD authentication. I am not sure on how to trigger the function from PCF component. I tried using msal.js, but that did not work. Azure function is hosted in the same tenant as that of CRM in which I've deployed the PCF. PFB the code I tried. Could you guys help me to authenticate to call the function app.

Here I try to get the token and then planning to use the token with header in the call to Azure Function. I also like to aquire a token without a login popup if possible.

 

 

import { AxiosRequestConfig } from 'axios';
import * as Msal from "msal";

var appConfig = {
 genScope: ["https://url.azurewebsites.net/user_impersonation"]
};

export const msalConfig: Msal.Configuration = {
 auth: {
 clientId: 'bd73****-****-****-****-****74179bb',
 authority: "https://login.microsoftonline.com/0417****-****-****-****-****0dfff06c",
 validateAuthority: false,
 redirectUri: "https://url.azurewebsites.net/.auth/login/aad/callback"
 },
 cache: {
 cacheLocation: "localStorage",
 storeAuthStateInCookie: true
 }
};

const msalInstance = new Msal.UserAgentApplication(msalConfig);

const loginRequest = {
 scopes: appConfig.genScope
};

const tokenRequest = {
 scopes: appConfig.genScope
};

function signIn() {
 msalInstance.loginPopup(loginRequest).then(function (loginResponse) {
 getToken(tokenRequest).then(tk => {
 console.log(tk);
 });
 }).catch(function (error) {
 console.log(error);
 });
}

//acquire a token silently
function getToken(tokenRequest: any) {
 return msalInstance.acquireTokenSilent(tokenRequest).catch(function (error) {
 console.log("aquire token popup");
 // fallback to interaction when silent call fails
 return msalInstance.acquireTokenPopup(tokenRequest).then(function (tokenResponse) {
 }).catch(function (error) {
 console.log("Failed token acquisition", error);
 });
 });
}

msalInstance.handleRedirectCallback((error, response) => {
 // handle redirect response or error
});

export const getTokens = (): Promise<any> => {
 return getToken(tokenRequest);
}

export const runFunction = (): Promise<any> => {
 const requestConfig: AxiosRequestConfig = {
 url: "https://url.azurewebsites.net",
 method: "GET"
 };

 const token = getTokens();
 // use token and call Azure Function APP

 return Promise.resolve(true);
}

 

 

 

I have the same question (0)
  • Diana Birkelbach Profile Picture
    3,072 Most Valuable Professional on at

    Hi @naveenrerd 

     

    My first impulse would be not to call it directly from the PCF.

     

    I would try to use a CustomAction, and implement the call to the azure function with a CRM WebHook (or PlugIn), because you don't have authentication issues.

    But there is still a problem with calling a CustomAction from the PCF: you need the "execute" method of the webAPI. In the PCF documentation , the WebAPI "execute" method is not documented (but it works), so it's actually unsupported for now. I'm not sure if that is a documentation issue or it's not supposed to work. Another way would be to implement the CustomAction call using the webAPI HttpRequest.

     

    It's a very interesting question. I'm also looking forward to see the other answers that will come. 

     

    Best regards,

    Diana

  • Ben Thompson Profile Picture
    1,400 on at

    @DianaBirkelbach I suspect the reason why execute isn't supported is because it execute could mean very different things in a canvas PCF component compared to a model driven PCF component.

     

    The code we use to call an action is just a standard XMLHttpRequest like below (it's hacked from two pieces to give you a promise that makes a post request.

     

    var req = new XMLHttpRequest();
    		var baseUrl=this.baseUrl;
    var query="/api/data/v9.1/hdn_ValidateLicense";
    		return new Promise(function (resolve, reject) {
    
    			req.open("POST", baseUrl + query, true);
    			req.onreadystatechange = function () {
    				
    				if (req.readyState !== 4) return;
    				if (req.status >= 200 && req.status < 300) {
    					
    					// If successful
    					try {
    						
    						var result = JSON.parse(req.responseText);
    						if (parseInt(result.StatusCode) < 0) {
    							reject({
    								status: result.StatusCode,
    								statusText: result.StatusMessage
    							});
    						}
    						resolve(req.responseText);
    					}
    					catch (error) {
    						throw error;
    					}
    
    				} else {
    					// If failed
    					reject({
    						status: req.status,
    						statusText: req.statusText
    					});
    				}
    
    			};
    			req.setRequestHeader("OData-MaxVersion", "4.0");
    			req.setRequestHeader("OData-Version", "4.0");
    			req.setRequestHeader("Accept", "application/json");
    			req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
    var body=	"{'ProductName': '"+productName+"'}";
    			req.send(body);
    		});

     

    And as you say actions are great ways to avoid security issues (I've often seen security people ask why does this website talk to xyz.com?). By using an action to call the function you bypass that pain and avoid any Cross Domain issues you may hit and you don't want those as debugging that is a complete nightmare as you will need to know the complete settings of a users browsers to identify whether it's an issue, a firewall issue or something else.

     

     

  • Diana Birkelbach Profile Picture
    3,072 Most Valuable Professional on at

    Hi @ben-thompson , 

    I agree with you, except that I don't understand the explanation why webAPI.execute is not documented for PCF.

    The "feature-usage" webAPI is not available for CanvasApps at all. This is only a Model-Driven App feature. So why should be a difference between webAPI.execute and webAPI.create (for instance)?

     

    The problem with self-made requests, is that it is a hard-coded url , at least the "/api/data/v9.1/" part (which will change, at least in version), and that I would need an own library for this requests, if I call it more often.

    But I agree, for now is the only supported way for CustomActions.

     

    Best regards,

    Diana

  • Ben Thompson Profile Picture
    1,400 on at

    The /api/data/v9.1 part is very unlikely to change as removing it would just break a pile of code without any real benefit - I suspect MS will just keep the existing versions going until a breaking change was required (and even then it will require 2 years of notice to avoid pain). 

  • Diana Birkelbach Profile Picture
    3,072 Most Valuable Professional on at

    Thanks @ben-thompson 

    I was hoping that the client-side webAPI feature would last longer than the webAPI version (or the endpoint itself), since it could be under the hood shifted to another endpoint (saw a lot of this breaking changes since CRM 1.2).

     

    Beside that, I'm not sure if webAPI feature is working offline. The Apps are designed for offline mode too (I know, not really, not for now).

    But now thinking about that, I think I just understood why the webAPI feature doesn't have an execute method: in the model-driven sdk (Xrm.WebApi), the execute method is only available for online mode. That would make the difference: the "execute" is not supported for pcf, because the "pcf webAPI feature" doesn't differentiate between online and offline.

    But thinking that way, the HttpRequest will not work offline at all. 🤔

     

    Best regards,

    Diana

  • naveenrerd Profile Picture
    16 on at

    Hi @DianaBirkelbach ,

     

    Thanks for your reply. But I would prefer to call the function app directly instead of calling it via a plugin. I am still keeping this issue open.

     

    Thanks

  • Danish N. Profile Picture
    186 on at

    @naveenrerd 

    Are you having issues authenticating or invoking Azure Functions? Also this is more of an Azure related question rather than PowerApps. You can call any HTTP request from PCF and that applies to Azure services as well.

    You can use MSAL Library for authentication, but I always had issues with it and have been using JQuery/XHR/Fetch for getting the token. Also, I normally would do an App Registrations and create a secret so I do not need to show Login Pop-up. Use registered App's Client Id and created Secret for Basic Auth and retrieve token.

    Once, token is retrieved; you can invoke the function (again using JQuery/XHR/Fetch) and pass in the retrieved token as Access Token in the header. 

    You can also validate your connections using Postman (which also provides you with code snippets)

    Below is the code that will provide you with access_token which can be used as a Bearer Token when calling Azure Function.

     

    const getAuthenticationToken = async function() {
     let config = require(__dirname + "/../config/config.json");
     var request = require('request');
     var options = {
     'method': 'POST',
     'url': 'https://login.microsoftonline.com/' + config.tenantId + '/oauth2/token',
     'headers': {
     'Authorization': 'Basic ' + new Buffer(config.clientId + ":" + config.clientSecret).toString('base64'),
     'Content-Type': 'application/x-www-form-encoded'
     },
     form: {
     'grant_type': 'client_credentials',
     'resource': 'your Azure function URL'
     }
     };
    
     return new Promise(
     (resolve, reject) => {
     request(options, function (error, response) {
     if (error) {
     reject(error);
     }
     resolve(JSON.parse(response.body));
     });
     }
     );
    }
    
    module.exports.getAuthenticationToken = getAuthenticationToken;

     


    ----
    Danish Naglekar | Power Maverick
    If this post helps, then please consider Accept it as the solution to help the other members.

  • naveenrerd Profile Picture
    16 on at

    Hi @PowerMaverick ,

     

    Thank you for you suggestion. As I am using frontend code, I cannot expose client secret as any user can read the client secret. This is again a security vulnerability. I am expecting something like aadhttp which SharePoint provides along with context so that AAD can be accessed with current logged in users.

     

    Thanks,

    Naveen Kumar Ravichandran

  • Verified answer
    RajYRaman Profile Picture
    270 on at

    @naveenrerd- You could follow a similar approach to this https://taerimhan.com/consuming-microsoft-graph-api-from-pcf-control/. Although this is for Graph API, the approach is something that you could use to execute Functions protected by Azure AD using the same MSAL library.

  • eleung83 Profile Picture
    232 on at

    I was also looking at using msal.js for our purpose but I did not want to use it in the PCF control as we load the control multiple times on the form, and multiple msal.js calls are unnecessary. So we do all the azure authentication on the form load instead

     

    I also didn't like much the idea of explicitly requesting scopes, so we've currently stuck with the latest version of adal.js available that allows us to authenticate an app registration to be able to execute an azure function

     

    From my recollection, if you get the login popup appearing and closing straightaway in both msal and adal.js, then you should get a bunch of key/value pairs relating to either the adal or msal authentication token in session storage (in your case it should be in local storage). For adal.js there'll be a key called "adal.access.token.key" suffixed with the id of the app registration you used to generate a token to authenticate to azure.

     

    You use the value in this key as the bearer token when you execute the azure request via js/ts by passing it in as the "Authorization" key in the header e.g. "Authorization": "Bearer {really long encoded string in adal.access.token.key storage value}"

     

    Also, as far as I know, the login popup is the only guaranteed way to generate the authentication token in CRM, you could use an older version of adal js (not sure if any versions of msal.js would work) and perform the authentication inside an iframe webresource to get around the login popup. Newer versions of adal.js inject an iframe into the dom and the src of that iframe automatically points to a Unified Interface htm page, which won't match up with the "allowed token audiences" configuration that you should have configured in Azure for the specific function app and also the redirect callback won't be executed

     

     

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Introducing the 2026 Season 1 community Super Users

Congratulations to our 2026 Super Users!

Kudos to our 2025 Community Spotlight Honorees

Congratulations to our 2025 community superstars!

Congratulations to the March Top 10 Community Leaders!

These are the community rock stars!

Leaderboard > Power Apps

#1
11manish Profile Picture

11manish 547

#2
WarrenBelz Profile Picture

WarrenBelz 444 Most Valuable Professional

#3
Valantis Profile Picture

Valantis 322

Last 30 days Overall leaderboard