AADB2C openidconnect-v2 sample causes "Bearer was forbidden" error when Authenticated Client Connects to Server

Siegfried Heintze 1,861 Reputation points
2020-12-24T04:42:30.51+00:00

Last spring I got this example to work and now I have created another new git clone and I'm having trouble again.

The problem occurs after successfully authenticating in the client and then pressing the "TodoList" link in the nav bar. The problem is in %SRCROOT%\active-directory-aspnetcore-webapp-openidconnect-v2-2\4-WebApp-your-API\4-2-B2C\Client\Services\TodoListService.cs Line 107 where the response.StatusCode is FORBIDDEN.

        var response = await _httpClient.GetAsync($"{ _TodoListBaseAddress}/api/todolist");  
        if (response.StatusCode == HttpStatusCode.OK)  
        {  
            var content = await response.Content.ReadAsStringAsync();  
            IEnumerable<Todo> todolist = JsonConvert.DeserializeObject<IEnumerable<Todo>>(content);  

            return todolist;  
        }  

Here is the log file from the TodoService:

info: Microsoft.AspNetCore.Hosting.Diagnostics[1]  
      Request starting HTTP/2 GET https://localhost:44332/    
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]  
      Request finished in 1039.6571ms 404   
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]  
      Request starting HTTP/1.1 GET https://localhost:44332/api/todolist    
info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[2]  
      Successfully validated the token.  
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]  
      Authorization failed.  
info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[13]  
      AuthenticationScheme: Bearer was forbidden.  
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]  
Request finished in 1395.9938ms 403  

Last spring I as able to fix this with the following code in the controller:

    [HttpGet]  
    //[Authorize(Policy = "ReadScope")]  
    [Authorize(Policy= "UserImpersonationScope")]  
    public IEnumerable<Todo> Get()  
    {  
        string owner = User.Identity.Name;  
        return TodoStore.Values.Where(x => x.Owner == owner);  
    }  

Here are my notes where I fixed the problem last spring with defining scopes in my tenant and I have not altered these since then.

Perhaps the problem is here: %SRCROOT%\active-directory-aspnetcore-webapp-openidconnect-v2-2\4-WebApp-your-API\4-2-B2C\TodoListService\AuthorizationPolicies\ScopesRequirement.cs(line 22). When I set a break point here I see the only accepted scope is "read". Should I not be seeing the other scopes I defined in my registrations in my tenant like "write" and "user_impersonation"?

However, the original C# code has

[Authorize(Policy = "ReadScope")]  

And this is not working with the new clone (and was not working with the old clone from last spring either). However, scopes read/write/user_impersonation are also defined in the registration of my Web API in my tenant.

When I check the API permissions in my Tenant Registrations for my client access to the WebAPI, I see read/write/user_impersonation are also still defined.

How can I fix this?

Mon Jan 04 2021 Update:
I'd like to ask a few more questions before I mark the answer

In the appsettings.json I see TodoListScope is defined for "read".

"TodoListScope": "https://fabrikamb2c.onmicrosoft.com/tasks/read"  

(1) What is the purpose of this statement and how does it relate to adding scopes in the C# code (as in Alfredo's code below)? Does this statement need to be enhanced for the additional scopes like user_impersonation and write?

(2) When might we want to modify this file? %SRCROOT%\aad-aspnetcore-webapp-openidconnect-v2\4-WebApp-your-API\4-2-B2C\TodoListService\AuthorizationPolicies\ScopesRequirement.cs

(3) How do we assign meaning to scopes like user_impersonation? I believe the only meaning they have is the way they are used in the authorize annotations in the controller... Is this true?

Thanks

Siegfried

Microsoft Entra ID
Microsoft Entra ID
A Microsoft Entra identity service that provides identity management and access control capabilities. Replaces Azure Active Directory.
20,107 questions
{count} votes

1 answer

Sort by: Most helpful
  1. 2020-12-30T22:42:22.483+00:00

    Hello, Ensure this is present in the TodoListService\Startup.cs:

       services.AddAuthorization(options => {  
       	options.AddPolicy("ReadScope", policy = >policy.Requirements.Add(new ScopesRequirement("read","write","user_impersonation")));  
       });  
    

    Also that your client is requesting any of those scopes so that the access token includes them.

    Please let me know if you need more help. If the answer was helpful to you, please accept it and, optionally, provide feedback so that other members in the community can benefit from it.