Search code examples
azureasp.net-coreazure-active-directoryopenid-connect.net-6.0

Getting Azure Error: IDW10203: The 'scope' or 'scp' claim does not contain scopes 'access_as_machine' or was not found


I am trying to setup client credentials authentication for machines (original question: Web API with Microsoft Identity Platform Authentication)

I am getting a valid token from https://login.microsoftonline.com/xxx/oauth2/v2.0/token.

However, I am receiving the following error when trying to call the secured action of my controller:

IDW10203: The 'scope' or 'scp' claim does not contain scopes 'access_as_machine' or was not found. 

This is how my controller action looks like:

[Authorize]
[HttpGet("GetAsMachine")]
[RequiredScope("access_as_machine")]
public string GetAsMachine() => $"Machine {Assembly.GetExecutingAssembly().GetName().Version}";

In client credentials I had to set my scope to "api://xxx/.default". When I try to set it to the actual scope, I am getting this error:

1002012: The provided value for scope api://xxx/access_as_machine is not valid. Client credential flows must have a scope value with /.default suffixed to the resource identifier (application ID URI).

Any idea what I am missing here?


Solution

  • Please notice one thing, when you want to use client credential flow, that means the token will contain roles claim but not the scp claim for delegate access token(generated by auth code flow/ropc flow..).

    Then when you want to authenticate token generated by client credential flow, you may follow this document.

    In brief, for example, I created a new .net 5 MVC project, and add configurations in appsettigns.json:

      "AzureAd": {
        "Instance": "https://login.microsoftonline.com/",
        "ClientId": "clientid_which_have_api_permission",
        "Domain": "tenantname.onmicrosoft.com",
        "TenantId": "common",
        "Audience": "clientid_of_the_app_exposed_api"//e.g: api://client_id
      }
    

    Then in Startup.cs, add services.AddMicrosoftIdentityWebApiAuthentication(Configuration, "AzureAd"); in ConfigureServices method and add app.UseAuthentication(); in Configure method.

    Then in my controller, I add an action like this:

    [Authorize(Roles = "Tiny.TestRead")]
    public string getData() {
         //HttpContext.ValidateAppRole("Tiny.TestRead");
         return "success";
    }
    

    Then I think you can notice I used Tiny.TestRead as target role name. This is defined in Azure ad and it requires you to expose an api with a role. And don't forget to add api permission.

    enter image description here enter image description here

    In my test, I only create 1 azure ad app, this app exposed an api(role type) then I add this api permission to itself. So I generate access token like this:

    enter image description here