0

I have created an on-premise .Net 6 Web API and have successfully implemented authN using Azure (app registration > access_token). This api is accessed publically by an external vendor in a service-2-service way.

Because the controller actions need to have AuthZ using RBAC (Role-based access control) I started searching on how to accomplish this for my scenario.

What I did is, create app roles on the API app registration and create a 2nd app registration (client) that has a "Read" role, now I can generate a separate access_token but it seems I have no way to check the role in the API?

enter image description here

Client app regstration

When using the client app registrations client_id and client_secret I only receive the access_token, no information on roles!

enter image description here

{
    "token_type": "Bearer",
    "expires_in": 3599,
    "ext_expires_in": 3599,
    "access_token": "TOKENHERE"
}

What I need is proper Role checking using Role-based authorization without a user but I'm missing some crucial information on how to set this up properly on Azure and in the API bootstrapper. Roles, scopes, claims, ..?

What am I overlooking here?

grmbl
  • 2,514
  • 4
  • 29
  • 54
  • 1
    From the screen shots it looks like you've setup your Azure AD App Registration correctly, which controls Authentication to your Function App. In terms of Authorization if you aren't using Azure API Manager I believe you will need to pass the `ClainsPrincipal` to the function execution and then write code to verify the groups that you want. Does this post help? https://medium.com/medialesson/role-based-authorization-in-azure-functions-with-azure-ad-and-app-roles-b1fed5714c91 – Kane Sep 13 '22 at 09:00
  • Thanks for the link @Kane, but the API is running on IIS hosted on-prem. And there are no users to assign. Just giving access to another API calling mine but with authZ preferably. – grmbl Sep 13 '22 at 09:10
  • Okay your comment provides a little more context. Assuming the authorizing App Reg is delegated you should be able to call the MS Graph API to get the groups using the bearer token. Alternatively if you have access to the ID_token this can be configured to include the groups. – Kane Sep 13 '22 at 09:15
  • Did you try decoding the generated access token in https://jwt.ms/? – Sridevi Sep 13 '22 at 09:25
  • @SrideviM, I decoded it but it's unclear for me what to do next. (use the claims to authorize the actions in the API) – grmbl Sep 13 '22 at 09:38

1 Answers1

1

I tried to reproduce the same in my environment and got below results:

I created App roles on the API App registration same as you like below:

enter image description here

I created another App registration for client and added Service.Read role by granting consent like below:

enter image description here

I generated access token for the application using Client Credentials grant type via Postman like below:

POST https://login.microsoftonline.com/<TenantID>/oauth2/v2.0/token

enter image description here

Using token endpoint URL, you will only get tokens in the response without displaying claims.

You can find the claims like roles, scp etc... only when you decode the token like below:

enter image description here

In order to use the claims to authorize the actions in the API, you can build and register policies like below:

In Program.cs:

builder.Services.AddAuthorization(options => { options.AddPolicy("Policy_Name", policy => policy.RequireClaim("Service.Read")); });

app.UseAuthorization();

In Controller file:

[Authorize(Policy = "Policy_Name")]  
public class YourClass : Controller {}

Please refer the below documents to get complete code samples:

Claims-based authorization in ASP.NET Core | Microsoft Docs

Role based access using client credentials by user4864425

Sridevi
  • 10,599
  • 1
  • 4
  • 17
  • Thanks! That seems like what I was after, I will try this and report back with findings. The only thing that seems a bit weird is that you need to add an app registration for each role you have (which we both did) because you need different access_tokens (with that role in it). Is this the recommended way for client credential flow login and authorization in a .Net web api? – grmbl Sep 14 '22 at 06:49
  • Instead of creating new app registration for every role, you can just grant **admin consent** to required **[API permissions](https://i.imgur.com/rXroSWx.png)** and generate access token only for them. You will get the **[roles in decoded token](https://i.imgur.com/sweZlL9.png)** based on what you consented. – Sridevi Sep 14 '22 at 10:48
  • I'd still need different app registrations when I need a client to access Admin functionality and another to access only with Read, right? I have tried with the current setup and I don't see the roles in the JWT. I'll try the setup again.. – grmbl Sep 14 '22 at 12:55
  • Please recheck the parameters you are using to generate token. It should be like **`client_id`** : AppId of Api dev Client read app and **`scope`**: api://AppId of Api dev/.default – Sridevi Sep 14 '22 at 13:05
  • Yes! That's it, I used the scope for the client app not the API app. – grmbl Sep 14 '22 at 13:09
  • 1
    You need to use API app for scope.... You won't get roles if both are swapped – Sridevi Sep 14 '22 at 13:11
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/248042/discussion-between-grmbl-and-sridevi). – grmbl Sep 14 '22 at 13:11