I have a single-page application (SPA) developed with Vue.js and hosted on Azure App Services that is using Azure B2C and MSAL 2.8.0 for authentication. The web APIs called by the SPA are developed with .NET 8.0 and implemented as Azure Functions (Function Apps). I want to use the same B2C tenant to authenticate the Azure Functions using Easy Authentication once the user is logged into the SPA. However, I keep receiving a 403 error code when I pass the CORRECT bearer token to the Functions App after user authentication. I have been following the guidance from this Microsoft documentation (https://learn.microsoft.com/en-us/azure/active-directory-b2c/configure-authentication-sample-spa-app) but have not had any success. See Picture of the Function App Authentication configuration
To authenticate Azure Function App using Azure B2C, check the below:
Create an Azure AD B2C application and expose an API:
Grant API permissions for the exposed scope:
Create Azure function and for sample I created an HTTP trigger:
Adding Identity provider as Microsoft and passed the values of Azure AD B2C application:
As you are using SPA authentication, configure the redirect URL as SPA with URL as https://YourfunctionAppName.azurewebsites.net/.auth/login/aad/callback
For sample, I generated token via Postman using PKCE:
client_id:ClientID
grant_type:authorization_code
callback_uri:https://rukfuncapp1.azurewebsites.net/.auth/login/aad/callback
code_challenge_method:SHA-256
scope:https://b2c.onmicrosoft.com/ClientID/API.Call
Generated access token:
The 403 error usually occurs if the access token does not contain correct scopes to perform the action.
To resolve the error, make sure to pass correct scope and correct redirect URL as I did.
- Check whether you are passing access token or ID token.
Make sure when decoded the contains scope:
When I used the above access token to call the Azure function it is successful like below:
https://rukfuncapp1.azurewebsites.net/api/HttpTrigger1?code=XXX
If the Azure function is not configured as Anonymous, then make sure to pass the header as x-functions-key : FunctionURLCodeValue
.