0

I have an API that I want to secure using client credential flow.

I have:

  • Registered an app in my Azure Active Directory
  • Added permission to User.ReadAll, granted admin access
  • Generated client secret

In my API code, Program.cs:

builder.Services.AddMicrosoftIdentityWebApiAuthentication(builder.Configuration);
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();

Appsettings.json:

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "myazure.onmicrosoft.com",
    "TenantId": "4b49fd73-aaaa-zzzz-xxxx-101385c03aaa",
    "ClientId": "226a511d-8888-7777-6666-c1897e7d4ccc"
  }
}

In my controller:

[Authorize]
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase

I did a POST to https://login.microsoftonline.com/mytenant/oauth2/v2.0/token and got an access token. I've validated the token at jwt.ms and it looks fine. But when I used that token to make API call I would get 401, Bearer error="invalid_token", error_description="The signature is invalid"

What am I missing?

EDIT: Okay, I finally found out what I was missing. I needed to define a specific client (the API's consumer), give it permission to my API, and then voila - everything will works.

This confuses me since the way I did it in Keycloak is I just need to define the API side, don't need to define the client at all.

Farid
  • 872
  • 1
  • 13
  • 30
  • If I had to guess, you most likely acquired an access token for Microsoft Graph API. What did you use for scopes in the client app? You need to use a scope defined in your API instead of a MS Graph API scope. – juunas Jun 02 '22 at 07:26
  • I did not define any scopes. Unless I misunderstand things, does client credential flow need scope? There is no consent screen for user to agree/disagree. – Farid Jun 02 '22 at 07:33
  • You still need to specify what API you want the access token for. In the v1 endpoint this would be the resource and with v2 endpoint that is the scope. In client credentials flow the scope is typically `api-client-id/.default` or `api-app-id-uri/.default`. – juunas Jun 02 '22 at 07:44
  • @Farid Yes you should have `scope` for [`credential credential flow`](https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow#get-a-token) as well – Md Farid Uddin Kiron Jun 02 '22 at 07:47
  • @Farid Could you please share how you are sending request for getting token? – Md Farid Uddin Kiron Jun 02 '22 at 08:28
  • You could [check the example here](https://stackoverflow.com/questions/69001458/asp-net-core-5-webapi-azure-ad-call-graph-api-using-azure-ad-access-token/69007174#69007174). Another similar issue [can be found here](https://stackoverflow.com/questions/68944805/how-to-fix-calling-getaccesstokenforappasync-to-acquire-token-resulting-in-a-nul/68947741#68947741). Set the [permission on azure portal like this](https://stackoverflow.com/questions/69831717/failed-to-acquire-ms-graph-token/69835012#69835012). Hope it will guided you accordingly. – Md Farid Uddin Kiron Jun 02 '22 at 08:39

0 Answers0