0

I have API protected by Azure AD where Authentication is required to get access data, where I expose the API with only one simple scope for now.

The API and client app both are registered in Azure AD. Roles are also configured for the API, only a a user with Admin role can call my API.

Do I need to assign this Admin role as well to the client App? or AccessApi scope is enough?

Scopes  Who can consent     Admin consent display name     User consent display name   State 

api://xx  User              AccessApi                      AccessApi                 Enable

And a client application build using webassembly blazor also registered in Azure AD, and its configured with Api permission to use delegated access to AccessApi.

API / Permissions name  Type       Description   Admin consent required    Status
myApi (1)   

AccessApi              Delegated     AccessApi              No

I configured webassembly blazor client application to authenticate against azure and get token and use that token to call myApi, however I keep getting loading but no data is being displayed without any error.

Im not sure what went wrong here ?

program class of client application:

 private static string scope = @"api://xxx/AccessApi";

...

            var builder = WebAssemblyHostBuilder.CreateDefault(args);
            builder.RootComponents.Add<App>("app");


            builder.Services.AddScoped<GraphAPIAuthorizationMessageHandler>();

            builder.Services.AddHttpClient("ServerAPI",
                client => client.BaseAddress = new Uri("https://localhost:44314"))
                .AddHttpMessageHandler<GraphAPIAuthorizationMessageHandler>();

            builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>()
                .CreateClient("ServerAPI"));

            builder.Services.AddMsalAuthentication(options =>
            {
                builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
                options.ProviderOptions.DefaultAccessTokenScopes.Add(scope);
            });

At fetch data razor page I imported all necessary libraries

@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@inject IAccessTokenProvider TokenProvider
@attribute [Authorize]

@inject NavigationManager UriHelper
@inject HttpClient Http

...

data = await Http.GetFromJsonAsync<data[]>(@"API-url--runs-locally-on-docker");

The authorization message handler class

 private static string scope = @"api://xxx/AccessApi";
    public GraphAPIAuthorizationMessageHandler(IAccessTokenProvider provider,
        NavigationManager navigationManager)
        : base(provider, navigationManager)
    {
        ConfigureHandler(
            authorizedUrls: new[] { "https://localhost:44314" },
            scopes: new[] { scope });
    }

After authenticated myself with Azure AD account, the client app shows loading.. but no data is being displayed. at the console level shows this error.

Failed to load resource: the server responded with a status of 401 (Unauthorized)

I followed Microsoft documentation and I'm not sure what I'm missing here. what could be wrong here ?

Update

The Api expose tab: enter image description here

Api permission for the client app: enter image description here

7
  • You could possibly help us help you by figuring out how far through Main() you get before the crash occurs. I don't have knowledge of this code environment, but you should step through it if you're able, otherwise delete code from the end of Main() backwards until it doesn't crash, and then you know the code you most recently deleted was where it crashed. Commented Apr 22, 2021 at 22:53
  • I added more description to the whole picture and work flow im trying to achieve. Commented Apr 23, 2021 at 11:56
  • Use jwt.ms to parse the access token and provide a screenshot. Commented Apr 28, 2021 at 7:36
  • I cant see where the token is been send to the Api. the data = await Http.GetFromJsonAsync<data[]>(@"API-url--runs-locally-on-docker"); does that automatically somehow Commented Apr 28, 2021 at 7:38
  • Can you provide a screenshot of Expose an API of the api application? By the way, you also need to add the client application to the api. i.sstatic.net/tG0co.png Commented Apr 28, 2021 at 7:47

1 Answer 1

1

Obviously, your scope is set incorrectly. You should set the scope to the client id of the api application instead of the client id of the client application. In your question, I think your scope should be: api://7b4d6df9-63cd-4ed7-881bxxx/AccessApi.

Parse the token and you should see scp claim and roles claim.

enter image description here

Sign up to request clarification or add additional context in comments.

17 Comments

Im lost here, can you please explain more? I defined scope in Api and that scope is used by the client application. what is wrong here?
@ikenahim The scope is only granted to the client application by you, and it will be displayed in the token.
@ikenahim Try it out according to my method and see how it turns out.
I created scope AccessApi in the Api and expose this scope, and the client application use this scope. I still dont understand you :/.
Do you mean the scope has be created in the client application ? not at the API?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.