0

I've created a simple HTTP Trigger function and linked it to the API management.

Then I've set the Cors policy in the API Management like this:

<policies>
<inbound>
    <cors>
        <allowed-origins>
            <origin>*</origin>
        </allowed-origins>
        <allowed-methods>
            <method>*</method>
        </allowed-methods>
    </cors>
</inbound>
<backend>
    <forward-request />
</backend>
<outbound />
<on-error />

When I call it from a blazor wasm, it gives the following error:

Access to fetch at 'https://example-api.azure-api.net/teste/Teste' from origin 'https://localhost:5001' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

A few points to notice:

  • When I call 'https://example-api/teste/Teste' directly from the browser, it works.
  • When I call the function from blazor wasm directly (without API management) it works.
  • When I call 'https://example-api/teste/Teste' from blazor wasm it gives the Cors Error mentioned.

Any ideias?

Guilherme Molin
  • 308
  • 4
  • 13

1 Answers1

0

Firstly, Registered with Azure AD to protect the Azure function and then

  1. Configure Redirect URI > Select Web > type <app-url>/.auth/login/aad/callback.

  2. Click on Implicit grant flow > define API scope and copy it

  3. Set up API permissions. Permissions to access function should be granted to your client application.

enter image description here

  • In your App Service app, enable Azure Active Directory and enable the CORS policy in Azure Function App.

Code

  1. Create the Custom class and name it as AuthorizationMessageHandler
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;

public class CustomAuthorizationMessageHandler : AuthorizationMessageHandler
{
    public CustomAuthorizationMessageHandler(IAccessTokenProvider provider, 
        NavigationManager navigationManager)
        : base(provider, navigationManager)
    {
        ConfigureHandler(
            authorizedUrls: new[] { "<your function app url>" },
            scopes: new[] { "<the function app  API scope your define>" });
    }
}

  1. In Program.cs file:
 public static async Task Main(string[] args)
        {
            var builder = WebAssemblyHostBuilder.CreateDefault(args);
            builder.RootComponents.Add<App>("app");
             // register CustomAuthorizationMessageHandler 
            builder.Services.AddScoped<CustomAuthorizationMessageHandler>();
            // configure httpclient
            // call the following code please add packageMicrosoft.Extensions.Http 3.1.0
            builder.Services.AddHttpClient("ServerAPI", client =>
              client.BaseAddress = new Uri("<your function app url>"))
                    .AddHttpMessageHandler<CustomAuthorizationMessageHandler>();
            // register the httpclient
            builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>()
             .CreateClient("ServerAPI"));
            // configure Azure AD auth
            builder.Services.AddMsalAuthentication(options =>
            {
                builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
                options.ProviderOptions.DefaultAccessTokenScopes.Add("<the function app  API scope your define>");


            });

            await builder.Build().RunAsync();
        }

  1. API Calling:
@page "/fetchdata"
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@inject HttpClient Http

<h1>Call Azure Function</h1>

<p>This component demonstrates fetching data from the server. </p>

<p>Result: @forecasts</p>

<button class="btn btn-primary" @onclick="CallFun">Call Function</button>

@code {
    private string forecasts;

    protected async Task CallFun()
    {
        forecasts = await Http.GetStringAsync("api/http");
    }


}

enter image description here

  • Thanks for the answer, but I already can call the function directly as in your example. The problem occurs when using "Azure API Management" as a gateway. – Guilherme Molin Oct 26 '21 at 13:54
  • @GuilhermeMolin, while calling the API, are you getting that error? –  Oct 26 '21 at 13:56
  • Calling the Azure Function directly works "https://xxx.azurewebsites.net/Teste" using the "azure api management" as gateway doesn't "example-api.azure-api.net/teste/Teste" which calls the former. – Guilherme Molin Oct 26 '21 at 16:19