title: How to store the token received in AcquireTokenAsync with Active Directory
body: <h3>Problem Statement</h3>
  
  <p>I am using .NET Core, and I'm trying to make a web application talk to a web API. Both require authentication using the <code>[Authorize]</code> attribute on all of their classes. In order to be able to talk between them server-to-server, I need to retrieve the validation token. I've been able to do that thanks to <a href="https://azure.microsoft.com/en-us/resources/samples/active-directory-dotnet-webapp-webapi-openidconnect-aspnetcore/" rel="noreferrer">a Microsoft tutorial</a>.</p>
  
  <h3>Problem</h3>
  
  <p>In the tutorial, they use a call to <code>AcquireTokenByAuthorizationCodeAsync</code> in order to save the token in the cache, so that in other places, the code can just do a <code>AcquireTokenSilentAsync</code>, which doesn't require going to the Authority to validate the user. </p>
  
  <blockquote>
    <p>This method does not lookup token cache, but stores the result in it, so it can be looked up using other methods such as AcquireTokenSilentAsync</p>
  </blockquote>
  
  <p>The issue comes in when the user is already logged in. The method stored at <code>OpenIdConnectEvents.OnAuthorizationCodeReceived</code> never gets called, since there is no authorization being received. That method only gets called when there's a fresh login.</p>
  
  <p>There is another event called: <code>CookieAuthenticationEvents.OnValidatePrincipal</code> when the user is only being validated via a cookie. This works, and I can get the token, but I have to use <code>AcquireTokenAsync</code>, since I don't have the authorization code at that point. According to the documentation, it</p>
  
  <blockquote>
    <p>Acquires security token from the authority.</p>
  </blockquote>
  
  <p>This makes calling <code>AcquireTokenSilentAsync</code> fail, since the token has not been cached. And I'd rather not always use <code>AcquireTokenAsync</code>, since that always goes to the Authority.</p>
  
  <h3>Question</h3>
  
  <p>How can I tell the token gotten by <code>AcquireTokenAsync</code> to be cached so that I can use <code>AcquireTokenSilentAsync</code> everywhere else?</p>
  
  <h3>Relevant code</h3>
  
  <p>This all comes from the Startup.cs file in the main, Web Application project.</p>
  
  <hr>
  
  <p>This is how the event handling is done:</p>
  
  <pre><code>app.UseCookieAuthentication(new CookieAuthenticationOptions()
  {
      Events = new CookieAuthenticationEvents()
      {
          OnValidatePrincipal = OnValidatePrincipal,
      }
  });
  
  app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
  {
      ClientId = ClientId,
      Authority = Authority,
      PostLogoutRedirectUri = Configuration["AzureAd:PostLogoutRedirectUri"],
      ResponseType = OpenIdConnectResponseType.CodeIdToken,
      CallbackPath = Configuration["Authentication:AzureAd:CallbackPath"],
      GetClaimsFromUserInfoEndpoint = false,
  
      Events = new OpenIdConnectEvents()
      {
          OnRemoteFailure = OnAuthenticationFailed,
          OnAuthorizationCodeReceived = OnAuthorizationCodeReceived,
      }
  });
  </code></pre>
  
  <p>And these are the events behind:</p>
  
  <pre><code>private async Task OnValidatePrincipal(CookieValidatePrincipalContext context)
  {
      string userObjectId = (context.Principal.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier"))?.Value;
      ClientCredential clientCred = new ClientCredential(ClientId, ClientSecret);
      AuthenticationContext authContext = new AuthenticationContext(Authority, new NaiveSessionCache(userObjectId, context.HttpContext.Session));
      AuthenticationResult authResult = await authContext.AcquireTokenAsync(ClientResourceId, clientCred);
  
      // How to store token in authResult?
  }
  
  private async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext context)
  {
      // Acquire a Token for the Graph API and cache it using ADAL.  In the TodoListController, we'll use the cache to acquire a token to the Todo List API
      string userObjectId = (context.Ticket.Principal.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier"))?.Value;
      ClientCredential clientCred = new ClientCredential(ClientId, ClientSecret);
      AuthenticationContext authContext = new AuthenticationContext(Authority, new NaiveSessionCache(userObjectId, context.HttpContext.Session));
      AuthenticationResult authResult = await authContext.AcquireTokenByAuthorizationCodeAsync(
          context.ProtocolMessage.Code, new Uri(context.Properties.Items[OpenIdConnectDefaults.RedirectUriForCodePropertiesKey]), clientCred, GraphResourceId);
  
      // Notify the OIDC middleware that we already took care of code redemption.
      context.HandleCodeRedemption();
  }
  
  // Handle sign-in errors differently than generic errors.
  private Task OnAuthenticationFailed(FailureContext context)
  {
      context.HandleResponse();
      context.Response.Redirect("/Home/Error?message=" + context.Failure.Message);
      return Task.FromResult(0);
  }
  </code></pre>
  
  <p>Any other code can be found in the linked tutorial, or ask and I will add it to the question.</p>