title: How does AAD API Access delegate permission work?
body: <p>I'm having a little trouble following how API Access delegate permissions work with azure active directory.  I feel like i'm probably misunderstanding a key aspect of how AAD works.</p>
  
  <p>Here is my set up</p>
  
  <ol>
  <li>I have a Web Application let’s call it WebApp.  I have created
  an AAD for the Web Application and registered with a AAD App ID. Let’s
  call it App ID A</li>
  <li>I have a Web Api let’s call it ApiService.  I have also created an AAD for it and registered with a AAD App ID.  Let’s all it App ID B.</li>
  <li>In AAD App ID A, I have updated the clicked on the API Access ->
  Required Permissions -> Add (App ID B ; Web API) permissions</li>
  <li>I’ve updated the manaifest in the AAD App ID B, to give consent to
  knownClientApplications to include the client ID of the Web App</li>
  <li>I’ve also enable oauth2AllowImplicitFlow to be true for both App’s
  manifest.</li>
  </ol>
  
  <p>What I’m trying to do is, A user signs into the web application sign.  When it signs in, the user is able to acquire a token for the specific Web App App ID A.  The user should be able to use that token and have access the Api Service with App ID B.  I thought by configuring the whole API Access -> Required Permissions within the Web Application it would give me delegate permission with the logged in user to communicate with the Api Service WebApi.  </p>
  
  <p>When I examine the JWT token, I notice that there is a claim for Microsoft Graph, but not for the ApiService.  Shouldn’t I be seeing a claim?</p>
  
  <p>When I try to use the token, it reacts with a 404 authentication error. </p>
  
  <p>Any advice appreciated,
  Thanks,
  Derek </p>
  
  <h2>UPDATE</h2>
  
  <p>In response to @joonasw</p>
  
  <p>I actually looked at the example you wrote when i started.  </p>
  
  <p><a href="https://joonasw.net/view/aspnet-core-2-azure-ad-authentication" rel="nofollow noreferrer">https://joonasw.net/view/aspnet-core-2-azure-ad-authentication</a></p>
  
  <p>In the example, the web application is initialized with:</p>
  
  <pre><code>.AddOpenIdConnect(opts =&gt;
          {
          Configuration.GetSection("OpenIdConnect").Bind(opts);
              opts.Events = new OpenIdConnectEvents
          {
              OnAuthorizationCodeReceived = ctx =&gt;
              {
                  return Task.CompletedTask;
              }
          };
          });
  </code></pre>
  
  <p>In the HomeController, there is code to retrieve the token for the graph api</p>
  
  <pre><code>private async Task&lt;string&gt; GetAccessTokenAsync()
  {
      string authority = _authOptions.Authority;
  
      string userId = User.FindFirstValue("http://schemas.microsoft.com/identity/claims/objectidentifier");
      var cache = new AdalDistributedTokenCache(_cache, _dataProtectionProvider, userId);
  
      var authContext = new AuthenticationContext(authority, cache);
  
      //App's credentials may be needed if access tokens need to be refreshed with a refresh token
      string clientId = _authOptions.ClientId;
      string clientSecret = _authOptions.ClientSecret;
      var credential = new ClientCredential(clientId, clientSecret);
  
      var result = await authContext.AcquireTokenSilentAsync(
          "https://graph.microsoft.com",
          credential,
          new UserIdentifier(userId, UserIdentifierType.UniqueId));
  
      return result.AccessToken;
  }
  </code></pre>
  
  <p>From my understanding, when the user initially login to the web application it will trigger the OnAuthorizationCodeReceived() method where it will be using the clientId/clientSecret/resource of the web applicaiton.  The token is stored in the distributed token cache under the key resource/client id.  </p>
  
  <p>In the example, GetAccessTokenAsync() is used to grab the token to access the graph API.  </p>
  
  <p>In my case, I was hoping to update that method to retrieve the token for the WebApi which has a different clientId/clientSecret/resoruce.  In my case, it will AcquireTokenSilentAsync will throw an AdalTokenAcquisitionExceptionFilter because the token needed is not stored in the cache and in the AdalTokenAcquisitionExceptionFilter  it will call try to reauthenticate</p>
  
  <pre><code>context.Result = new ChallengeResult();
  </code></pre>
  
  <p>which will redirect to the authentication page and then hits the AddOpenIdConnect() method.  However, the openIdConnect is configured with the web app clientID/ClientSecret/Resource and will not store the new token properly.  It will try to call GetAccessTokenAsync() again and the whole process will go in an infinite loop.  </p>
  
  <p>In the example, if you were to comment out the "Anthentication:resource" in app.settings, you will experience the same issue with the infinite loop.  What happens is that you initially authenticate correctly with no resource specified.  Then when you click on you try to get the token for microsoft graph which is a new resource, it can't find it in the cache and then tries to reauthenticate over and over again.</p>
  
  <p>I also notice that the acquireAsyncAuthentication only returns a AuthenticationResult with a bearer tokentype.  How would you get the refresh token in this case? </p>
  
  <p>Any advice?
  Thanks,
  Derek</p>
  
  <h2>UPDATE (Solution)</h2>
  
  <p>Thanks to @jaanus.  All you have to do is update the resource to the clientid of the web api and pass that into AcquireTokenSilentAsync.  The web api id uri that you can get from the azure portal did not work.  </p>