working example of OnBehalfOfProfider for a daemon app calling MS Graph

302 views Asked by At

I have difficulty finding a working example for this scenario:

IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
.Create(clientId)
.WithRedirectUri(redirectUri)
.WithClientSecret(clientSecret)
.Build();

OnBehalfOfProvider authProvider = new OnBehalfOfProvider(confidentialClientApplication, scopes);

Issues I am facing: 1.what package I get the OnBehalfOfProfider from? 2.assuming I have to get an AAD User's access token, without user's actual login (it's a daemon app) - how do I build the UserAssertion instance?

the info here is based on two sources: MSDN 'on behlaf of provider' https://learn.microsoft.com/en-us/graph/sdks/choose-authentication-providers?tabs=CS#OnBehalfOfProvider and github's 'how to call OBO' https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/on-behalf-of

thanks Art

1

There are 1 answers

2
juunas On

On behalf of flow is used when you have an API that receives an access token that contains user info, and you want to call another API as that user. That doesn't sound like your scenario here.

This sounds more like an unattended background access kind of scenario. There are essentially two options:

  1. Use refresh token flow
  2. Use client credentials flow
  3. Use ROPC flow

The first approach is more complex but is the recommended approach for non-critical processes. MSAL does simplify it quite a bit. The way it works:

  1. User authenticates to your app with e.g. authorization code flow
  2. MSAL stores the refresh token in a good token cache (database/Azure Key Vault etc.), you need to configure this
  3. Your background processor uses the same token cache, allowing it to use the refresh token to get new tokens

The downside of this approach is that it is a bit more complex and that the refresh tokens can expire, requiring users to re-authenticate.

The second approach is simpler but requires the use of application permissions instead of delegated permissions. With client credentials, your app needs to have access by itself to all of the data, without any user. So this requires a lot of access and relies on the API supporting this approach. But it is simple and reliable.

The third approach is one I would not recommend. It requires you to use the user's username and password to get tokens for the user. Not only do you need to store the users' passwords, it doesn't work at all if the user has multi-factor authentication enabled, is a guest user etc.