title: Calling Graph API from ASP.Net Core API on behalf of user from SPA
body: <p>I'm building an API which is called by a SPA (angular).
  The user is authenticated using Azure AD and the API uses AzureAdBearer for its authentication.</p>
  
  <pre><code>public void ConfigureServices(IServiceCollection services)
  {
   [...]
      services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme)
              .AddAzureADBearer(options =&gt; Configuration.Bind("AzureActiveDirectory", options));
   [...]
  }
  </code></pre>
  
  <p>I need to call Graph API and would like to do it on behalf of the connected user.
  I have seen this question: <a href="https://stackoverflow.com/questions/53732255/accessing-ms-graph-from-api-on-behalf-of-user-currently-signed-in-to-separate-we/53733028">Accessing MS Graph from API on behalf of user currently signed in to separate web client</a> which really looks like the solution I try to implement.
  I try to replicate this proposed solution here: <a href="https://joonasw.net/view/azure-ad-on-behalf-of-aspnet-core" rel="nofollow noreferrer">https://joonasw.net/view/azure-ad-on-behalf-of-aspnet-core</a>
  As I understand it I need to configure the JwtBearer settings, but how can I call the <code>.AddJwtBearer</code> if I already have <code>.AddAzureADBearer</code>.
  AddAzureADBearer itself calls the AddJwtBearer (cf. <a href="https://github.com/aspnet/AADIntegration/blob/master/src/Microsoft.AspNetCore.Authentication.AzureAD.UI/AzureADAuthenticationBuilderExtensions.cs#L66" rel="nofollow noreferrer">here</a>)</p>
  
  <p>I created a secret in the app registration of my API and used it to implement a <code>IAuthenticationProvider</code> to get the token on behalf of the user, but I get an error AADSTS65001.
  I guess this is because I'm missing the AddJwtBearer configuration to save the user's token in cache, but I'm not really sure.</p>
  
  <p>I don't really understand the solution proposed on the question <a href="https://stackoverflow.com/a/53803315/4606752">here</a>.</p>
  
  <p>UPDATE</p>
  
  <p>Thanks to <a href="https://stackoverflow.com/a/59606240/4606752">Tony Ju's answer</a> I have been able to authenticate. But when I call graph api I get Authorization_RequestDenied Insufficient privileges to complete the operation.</p>
  
  <p>I don't know why but can't manage to configure Fiddler properly to capture the request to Azure AD. I enabled ADAL logs and got this </p>
  
  <pre><code>[Information][False]: 2020-01-09T09:11:12.1104926Z: AdalLoggerBase.cs: ADAL PCL.CoreCLR with assembly version '5.2.4.0', file version '5.2.4.0' and informational version '5.2.4' is running...
  [Information][True]: 2020-01-09T09:11:12.1183853Z: AdalLoggerBase.cs: === Token Acquisition started:
  Authority: https://login.microsoftonline.com/d6397071-8e3e-45d2-a2d6-36698acf0fea/
  Resource: https://graph.microsoft.com
  ClientId: [...]
  CacheType: Microsoft.IdentityModel.Clients.ActiveDirectory.TokenCache (0 items)
  Authentication Target: User
  
  [Verbose][False]: 2020-01-09T09:11:12.1395851Z: AdalLoggerBase.cs: Username provided in user assertion - False
  [Verbose][False]: 2020-01-09T09:11:12.5277838Z: AdalLoggerBase.cs: Loading from cache.
  [Verbose][False]: 2020-01-09T09:11:12.5395969Z: AdalLoggerBase.cs: Looking up cache for a token...
  [Information][False]: 2020-01-09T09:11:12.5467711Z: AdalLoggerBase.cs: No matching token was found in the cache
  [Information][False]: 2020-01-09T09:11:12.5706903Z: AdalLoggerBase.cs: No matching token was found in the cache
  [Verbose][False]: 2020-01-09T09:11:12.5736362Z: AdalLoggerBase.cs: Looking up cache for a token...
  [Information][False]: 2020-01-09T09:11:12.5764248Z: AdalLoggerBase.cs: No matching token was found in the cache
  [Verbose][False]: 2020-01-09T09:11:12.5804061Z: AdalLoggerBase.cs: Either a token was not found or an exception was thrown.
  [Verbose][False]: 2020-01-09T09:11:12.5844932Z: AdalLoggerBase.cs: Cannot invoke the broker directly, may require install ...
  [Verbose][False]: 2020-01-09T09:11:12.5891021Z: AdalLoggerBase.cs: Check and AcquireToken using broker
  [Verbose][False]: 2020-01-09T09:11:12.5919785Z: AdalLoggerBase.cs: Broker invocation is NOT required
  [Verbose][False]: 2020-01-09T09:11:12.9510499Z: AdalLoggerBase.cs: Storing token in the cache...
  [Verbose][False]: 2020-01-09T09:11:12.9583491Z: AdalLoggerBase.cs: An item was stored in the cache
  [Information][True]: 2020-01-09T09:11:12.9917987Z: AdalLoggerBase.cs: === Token Acquisition finished successfully. An access token was returned: Expiration Time: 09/01/2020 10:10:54 +00:00Access Token Hash: GtaeLmKsVSj82umwxVcgghW3/X/N2hKhaxyb7XBbBU0=
   User id: 3b224748-42c5-406d-a0c0-e9c9f5238361
  </code></pre>
  
  <p>I used this code to get the token:</p>
  
  <pre><code>var userAssertion = new UserAssertion(token, "urn:ietf:params:oauth:grant-type:jwt-bearer", user.upn);
  var authContext = new AuthenticationContext(_aadOptions.Authority);
  var clientCredential = new ClientCredential(_aadOptions.ClientId, _aadOptions.ClientSecret);
  
  var result = await authContext.AcquireTokenAsync("https://graph.microsoft.com", clientCredential, userAssertion);
  </code></pre>
  
  <p>I tried to rewrite it for MSAL instead of ADAL but didn't success.
  Should the scope needed for the graph api request should be in the initial user login or do we expand the scope in the on-behalf-of user request token ?</p>