0

Application -

  1. .Net 6 web API
  2. Angular frontend
  3. SQL DB
  4. .Net 6 Windows Service

I need to achieve following - Authorization code flow, where angular app get the auth code and send it to .net 6 web api, which internally get the access token by auth code. Then .net 6 windows service internally uses that token to call graph api and also refresh the token if expired without user interaction.

Application users - User can be multi-tenant

With my current research Microsoft doc shows way to get the auth code flow done with web app or with angular, I don't want this to be done at frontend, I'm confused how to achieve above scenarios, if anyone can direct me to a path would help me a lot, thanks.

Ishika Jain
  • 949
  • 2
  • 11
  • 23
  • generate access token should be generated in the angualr app via the auth code, then using the access token to visit the api, and inside the api, using on behalf of flow to generate another access token and use it to call graph api. For the API project, it should validate the access token, but not he auth code. If you want an API which is `allowannoymous` to receive the auth code, then....hmmm why not using client crednetial flow.... – Tiny Wang Aug 30 '23 at 05:36
  • may be you are correct, 1. do you have any sample code which uses client credential flow, I referred several MSAL3 docs but having confusion ? 2. if we use client credential can we multi tenants or is it like specific to 1 tenant Id? – Ishika Jain Aug 30 '23 at 10:03
  • sample code: https://stackoverflow.com/a/74133928/14574199 – Tiny Wang Aug 30 '23 at 10:16
  • I never test multi-tenant in client credential flow, but I trust you need to get admin consent before using this flow. https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow#request-the-permissions-from-a-directory-admin – Tiny Wang Aug 30 '23 at 10:18
  • you can find code samples here https://learn.microsoft.com/en-us/azure/active-directory/develop/sample-v2-code?tabs=apptype#samples-and-guides – Tiny Wang Aug 30 '23 at 10:24

1 Answers1

0

In my humble opinion, Angular client app + .net core web api, this scenario, we should put the authentication and authorization part into angular project, so that users could sign in and generate access token to call API.

Inside the API, if we have the requirement to call MS graph API, we could use on-behalf-of flow to generate access token. Using on-behalf-of flow in the api project, we just need to add authentication scheme and inject graph SDK or token acquisition service. This flow, maybe you can take a look at this code snippet.

StringValues authorizationToken;
HttpContext.Request.Headers.TryGetValue("Authorization", out authorizationToken);
var token = authorizationToken.ToString().Replace("Bearer ","");
var scopes = new[] { "User.Read.All" };
var tenantId = "xxxx";
var clientId = "xxxx";
var clientSecret = "xxxx";
var onBehalfOfCredential = new OnBehalfOfCredential(tenantId, clientId, clientSecret, token);
var tokenRequestContext = new TokenRequestContext(scopes);
var token2 = onBehalfOfCredential.GetTokenAsync(tokenRequestContext, new CancellationToken()).Result.Token;
var graphClient = new GraphServiceClient(onBehalfOfCredential, scopes);
var user = await graphClient.Users.GetAsync();

By the way, when we sign in with auth code flow, it should ask us to give consent after entering password and user name if we didn't give admin consent in Azure AD api permission blade, for client credential flow, it's necessary to give admin consent. And if we used client credential flow for multi-tenant scenario, I'm afraid we should pass the admin consent step in advance.

https://login.microsoftonline.com/common/adminconsent?client_id=xxxe&state=12345&redirect_uri=http://localhost/myapp/permissions

client credential flow code sample, this is based on package Microsoft.Graph v4.x, using v5.x should have some differences:

using Microsoft.Graph;
using Azure.Identity;

var scopes = new[] { "https://graph.microsoft.com/.default" };
var tenantId = "tenant_name.onmicrosoft.com";//common for multi-tenant
var clientId = "aad_app_id";
var clientSecret = "client_secret";
var clientSecretCredential = new ClientSecretCredential(
                tenantId, clientId, clientSecret);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
var res = await graphClient.Users["{user-id}"].Messages["{message-id}"].Request().GetAsync();
Tiny Wang
  • 10,423
  • 1
  • 11
  • 29