azuresharepointazure-functionsspfx

Calling azure function from spfx webpart result 401 Unauthorized


i am trying to call Azure Function secured by AD from sharepoint webpart. But still getting 401 Unauthorized. Thanks for any advice. I tryid many tutorials but it looks like that even official documentation on microsoft sites are not up to date, because the is no authentication & authorization in Azure Function in Azure portal...

Here is steps i made:

Create default azure function in local. Azure function is anonymous and return just string "Hello world".

Create azure function in Azure portal and upload azure function from local to cloud.

Test azure function using browser/Powershell(Invoke-WebRequest) - works fine, return string "Hello World"

Add identity and Authorization to Azure Function:

Identity provider: Microsoft https://imgur.com/k2WCjyJ

create new app registration with name : AuthenticationFunctionAppAZF

Client secret setting name = MICROSOFT_PROVIDER_AUTHENTICATION_SECRET

Issuer_URL= 'https://login.microsoftonline.com/common/v2.0'

Allowed token audiences: 8bdb826f-bbbc-4f6b-923a-63777a5c3550(Client ID of registration)

Client application requirement: Allow Requst only from app. itself

Identity requirement: Allow request form any identity

Tenant Requirement: Allow request from specific tenant, allowed tenant is ID of my tenant

In App registration(AuthenticationFunctionAppAZF) of my Azure Function(AuthenticationFunctionAppAZF) In authentication i put:

In web application:

'https://oauth.pstmn.io/v1/browser-callback - for testing using postman' 'https://authenticationfunctionappazf.azurewebsites.net/.auth/login/aad/callback'

Allowed Tokens

Allowed ID Tokens

Set Supported account types: unts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant)

Permission API: https://imgur.com/a/wnb47h8

In Expose API: https://imgur.com/gAdpIc9

change Application ID URI: to 'https://tenantname.onmicrosoft.com/ClientID_of_AzureAppRegistration_of_My_Function'

Add scopes: user_impersonation access_as_user

When i testing using browser and go to this page : 'https://authenticationfunctionappazf.azurewebsites.net/.auth/login/aad/callback' then i log in to azure portal, then i try call my function url using url: 'https://authenticationfunctionappazf.azurewebsites.net/api/AuthenticationFunctionAppAZF?'

I get correct response: "Hello world!"

Then i create my spfx webpart using yo generator, here is my code which call azure function using aadhttpclient:

import * as React from 'react';
import { useState } from 'react';
import { AadHttpClient, IHttpClientOptions, HttpClientResponse } from '@microsoft/sp-http';
import { WebPartContext } from '@microsoft/sp-webpart-base';

export interface IHelloUserProps {
        context: WebPartContext;
}

export interface IHelloWorld {
        hello: string;
}

const HelloUser: React.FC<IHelloUserProps> = ({ context }) => {
        const [hello, setHello] = useState<IHelloWorld | null>(null);

        const fetchUserData = () => {
                console.log('Fetching user data...');
                if (!context) {
                        console.error('Context is undefined');
                        return;
                }

                console.log('Context:', context);
                if (!context.aadHttpClientFactory) {
                        console.error('aadHttpClientFactory is undefined');
                        return;
                }

                console.log('aadHttpClientFactory:', context.aadHttpClientFactory);

                const options: IHttpClientOptions = {
                        headers: {
                                'Accept': 'application/json;odata.metadata=none'
                        }
                };
                context.aadHttpClientFactory
                        .getClient('https://artetechnology.onmicrosoft.com/8bdb826f-bbbc-4f6b-923a-63777a5c3550')
                        .then((client: AadHttpClient): void => {
                                console.log('AadHttpClient obtained:', client);
                                client
                                        .get('https://authenticationfunctionappazf.azurewebsites.net/api/AuthenticationFunctionAppAZF?', AadHttpClient.configurations.v1, options)
                                        .then((response: HttpClientResponse): Promise<any> => {
                                                console.log('Response received:', response);
                                                return response.json();
                                        })
                                        .then((user: any): void => {
                                                console.log('User data:', user);
                                                setHello(user);
                                        })
                                        .catch((error: any): void => {
                                                console.error('Error parsing response:', error);
                                        });
                        })
                        .catch((error: any): void => {
                                console.error('Error getting AadHttpClient:', error);
                        });
        };

        return (
                <div>
                        <button onClick={fetchUserData}>Fetch User Data</button>
                        {hello ? <div>Hello, {hello.hello}</div> : <div>Loading...</div>}
                </div>
        );
};

export default HelloUser;

After i call my Azure function from sharepoint webpart local workbench i get this errors: https://imgur.com/4dR3UIf After i call from sharepoint webpart i get this error: https://imgur.com/blcSALB

Here is settings for CORS: https://imgur.com/T6mdUtJ


Solution

  • I find out solution, in code for aadhttpclientFactory in .getClient must be ID of Azure Function registration and in authentication for Azure Function in Additional checks must be either: Allow requests from specific client applications(You must insert ClientID for SharePoint Online Client Extensibility Web Application Principal if you calling azure function from Sharepoint WebPart) or Allow requests from any application (Not recommended)

    Then it works even in local workbench