Linda Lawton - DaImTo
Linda Lawton - DaImTo

Reputation: 116938

How to authenticate protect a backend web api for server to server communication using Azure Ad client_credentials

I have a curl script which requests a new access token from Azure AD. I need it to return a claim of some kind for my API, either a role or a scope either will work.

I can get an access token however its not returning a role claim or a scope or anything of that nature.

When used in the web API

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)                 
   .AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAd"));

I get:

Neither scope or roles claim was found in the bearer token.

I did try setting

"AllowWebApiToBeAuthorizedByACL" : true,

In appsettings.json but it did not stop the error from coming as it was supposed to do.

This is being used to authorize between a curl script and a microservice. As its a background service there is no user interaction its just server to server authorization. I am simply trying to protect the web api. So for security reasons I want to be sure that the access token created is in fact an access token for this system that's why im looking for some kind of claim or role on my application to ensure that its not just a random access token from another part of the system.

Without a role or a scope my application is throwing the following error

System.UnauthorizedAccessException: IDW10201: Neither scope or roles claim was found in the bearer token.

Oauth2 uses scopes to enable a user to grant a client access to their data as this does not require that I don't think what I am looking for her is scopes. I think what I need is a way to define a role for the application itself. I have very little experience with azure so please correct me if i'm wrong.

curl script

curl -X POST -d "grant_type=client_credentials&client_id=api://a4994a31-c494-4b73-9622-d3a7144abeee&client_secret=[secret]&resource=api://a4994a31-c494-4b73-9622-d3a7144abeee" https://login.microsoftonline.com/1e2ad6d6-274f-43e8-89ef-d36d65bb83b5/oauth2/token

Response

    {
      "aud": "api://a4994a31-c494-4b73-9622-d3a7144abee",
      "iss": "https://sts.windows.net/1e2ad6d6-274f-43e8-89ef-d36d6583b5/",
      "iat": 1628506854,
      "nbf": 1628506854,
      "exp": 1628510754,
      "aio": "E2ZgYChZ8/PRc/eJ5sYfulfVXWUrBQA=",
      "appid": "a4994a31-c494-4b73-9622-d3a7144abeee",
      "appidacr": "1",
      "idp": "https://sts.windows.net/1e2ad6d6-274f-43e8-89ef-d36d65bb835/",
      "oid": "81f74198-ab14-4b0b-bad6-62893e15f9c8",
      "rh": "0.AQsA1tYqHk8n6EOJ79NtZbuDtTFKmaSUxHNLliLTpxRKvu4AAA.",
      "sub": "81f74198-ab14-4b0b-bad6-62893e15f9c",
      "tid": "1e2ad6d6-274f-43e8-89ef-d36d65bb83b",
      "uti": "FaZGzuuRn0eEQYPRReoYAQ",
      "ver": "1.0"
    }

I tried setting up a scope

enter image description here

and then adding it to the curl script

curl -X POST -d "grant_type=client_credentials&client_id=api://a4994a31-c494-4b73-9622-d3a7144abeee&client_secret=[Secret]&resource=api://a4994a31-c494-4b73-9622-d3a7144abeee&scope=api://a4994a31-c494-4b73-9622-d3a7144abeee/load_scope" https://login.microsoftonline.com/1e2ad6d6-274f-43e8-89ef-d36d65bb83b5/oauth2/token

There was no effect at all the access token still does not contain any scopes.

Then i tried adding a role

enter image description here

add adding the role to the resource

curl -X POST -d "grant_type=client_credentials&client_id=api://a4994a31-c494-4b73-9622-d3a7144abeee&client_secret=[secret]&resource=api://a4994a31-c494-4b73-9622-d3a7144abeee/load" https://login.microsoftonline.com/1e2ad6d6-274f-43e8-89ef-d36d65bb83b5/oauth2/token

but that just returns an error

{"error":"invalid_resource","error_description":"AADSTS500011: The resource principal named api://a4994a31-c494-4b73-9622-d3a7144abeee/load was not found in the tenant named 1e2ad6d6-274f-43e8-89ef-d36d65bb83b5. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You might have sent your authentication request to the wrong tenant.

manifest

I am currently following Assign app roles to applications This is the manifest.

"appId": "51bdea30-a886-47f7-a27f-994c8caca5c",
    "appRoles": [
        {
            "allowedMemberTypes": [
                "Application"
            ],
            "description": "myapprole",
            "displayName": "myapprole",
            "id": "bdaa8bc7-e0b3-47b1-b92-9011313e16ae",
            "isEnabled": true,
            "lang": null,
            "origin": "Application",
            "value": "myapprole"
        }
    ],

Upvotes: 3

Views: 2307

Answers (1)

Linda Lawton - DaImTo
Linda Lawton - DaImTo

Reputation: 116938

The solution was to add AllowWebApiToBeAuthorizedByACL this removes the error message and allows to backend services to communicate without the need for roles or claims.

System.UnauthorizedAccessException: IDW10201: Neither scope or roles claim was found in the bearer token.

I had added it but it wasnt working after digging around in the source code for Microsoft.Identity.Web. I found that I was on an older version of Microsoft.Identity.Web which was apparently prior to the addition of the AllowWebApiToBeAuthorizedByACL check. I deleted the NuGet Package and readded it at 1.15.2 and it works.

 "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "[Redacted]",
    "ClientId": "[Redacted]",
    "TenantId": "[Redacted]",
    "AllowWebApiToBeAuthorizedByACL" : true,
    "CallbackPath": "/signin-oidc"
  },

Upvotes: 8

Related Questions