Search code examples
asp.net-corepowerapps

Powerapp Custom Connector for Azure AD protected ASP.Net Core WebAPI - getting Unauthorized 401


I'm trying to create an MS Powerapp Custom Connector to access an ASP.NET core WebAPI, which is protected by Azure AD using the Microsoft.Identity.Web package. But no matter how I try to set things up, I'm always getting a 401 when trying to access the API via the connector.

So my setup looks like this:

Azure App registrations

I have registered two apps in Azure App Registrations. One for the API and one for the Powerapp Connector.

For the API registration I only configured settings under 'Expose an API'. I set an Application ID URI

api://f9****ca-****-****-****-3d30e9e*****

and added a scope

api://f9****ca-****-****-****-3d30e9e*****/Employees.Read.All

I also added an authorized client application using the ID of the App registration for the Powerapp (config below).

The app registration for the Powerapp is configured as follows:

For authentication the Web platform is added with redirect URI of https://global.consent.azure-apim.net/redirect.

Under 'Certificates & secrets' I added a client secret.

Under 'Api permissions' I added a permission for the scope of the API api://f9****ca-****-****-****-3d30e9e*****/Employees.Read.All as Delegated permission.

Powerapp Custom Connector config

The security tab of my custom connector is configured as follows:

Setting Value
Auth type OAuth 2.0
Identity Provider Azure Active Directory
Client id <Client ID of App reg for Powerapp>
Client Secret <Client secret of App reg for Powerapp>
Login URL https://login.windows.net
Tenant ID <AAD Tenant ID>
Resource URL api://f9****ca-****-****-****-3d30e9e***** <Application ID URI of App reg for API>
Scope api://f9****ca-****-****-****-3d30e9e*****/Employees.Read.All

ASP.net core (3.1) Web App

I'm using the Microsoft.Identity.Web nuget package.

In my app config I added the following:

"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"ClientId": "<Client ID of app reg for API>",
"TenantId": "<Tenant ID>"
}

The startup class looks like this:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMicrosoftIdentityWebApiAuthentication(Configuration);
        services.AddControllers();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        
        app.UseHttpsRedirection();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
}

My controller is just decorated with the [Authorize] attribute.

Now, when I try to test an operation on the custom connector the WebAPI allways returns a 401 Unauthorized and I can't for the life of me figure out why.

I get see, that the request header has a Bearer token for the user I'm using to create the connection. So a token is issued, but somehow the WebApi deems it invalid.

Interestingly the audience in that token is https://apihub.azure.com. Shouldn't it be the client id of the app reg? Anyway, even if I add that audience to the valid audiences in my WebAPI, I still get the 401...

Is there anything I am missing here? Any help would be really appreciated.


Solution

  • You forgot to add the Authenction middleware.

    app.UseAuthentication();
    app.UseAuthorization();