title: AADSTS90094: "The grant requires admin permission " but admin consent but was already granted
body: <p>I have a multi-tenant native app that calls device information from the Microsoft Graph. There is no Web API between the native app and the Microsoft Graph. The scopes being requested are: User.Read, Directory.Read.All, Device.Read</p>
  
  <p>From the customer tenant, the customer admin has granted permissions to the app using the following URL: </p>
  
  <pre><code>https://login.microsoftonline.com/{Tenant Domain}/oauth2/authorize?client_id={ClientID Of App}&amp;response_type=code&amp;prompt=admin_consent
  </code></pre>
  
  <p>After completing, the return has the consented value as TRUE and the app appears in Azure AD -> Enterprise Applications -> All Applications -> {App Name} with the "permissions" section showing all 3 permissions against Microsoft Graph as "Delegated" and Granted by "An administrator".</p>
  
  <p>When the admin of the customer tenant logs into the app afterward, the app works as expected. However, if a non-admin user tries to log into the app, they receive an error after logging in: </p>
  
  <blockquote>
    <p>Need admin approval - {App name} needs permission to access resources
    in your organization that only an admin can grant. Please ask an admin
    to grant permission to this app before you can use it. Message:
    AADSTS90094: The grant requires admin permission.</p>
  </blockquote>
  
  <p>Again, the admin has already consented to the app.</p>
  
  <p>Additionally, the app manifest in the developer company's tenant shows in Azure AD -> App registrations -> (Filter of "All Apps" -> {App Name} -> Manifest shows:</p>
  
  <pre><code>{
      "appId": "{Hidden from StackOverflow}",
      "appRoles": [],
      "availableToOtherTenants": true,
      "displayName": "{Hidden from StackOverflow}",
      "errorUrl": null,
      "groupMembershipClaims": null,
      "optionalClaims": null,
      "acceptMappedClaims": null,
      "homepage": null,
      "informationalUrls": {
          "privacy": null,
          "termsOfService": null
      },
      "identifierUris": [],
      "keyCredentials": [],
      "knownClientApplications": [],
      "logoutUrl": null,
      "oauth2AllowImplicitFlow": false,
      "oauth2AllowUrlPathMatching": false,
      "oauth2Permissions": [],
      "oauth2RequirePostResponse": false,
      "objectId": "{Hidden from StackOverflow}",
      "parentalControlSettings": {
          "countriesBlockedForMinors": [],
          "legalAgeGroupRule": "Allow"
      },
      "passwordCredentials": [],
      "publicClient": true,
      "replyUrls": [
          "{Hidden from StackOverflow}"
      ],
      "requiredResourceAccess": [{
          "resourceAppId": "00000003-0000-0000-c000-000000000000",
          "resourceAccess": [{
                  "id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d",
                  "type": "Scope"
              },
              {
                  "id": "06da0dbc-49e2-44d2-8312-53f166ab848a",
                  "type": "Scope"
              },
              {
                  "id": "11d4cd79-5ba5-460f-803f-e22c8ab85ccd",
                  "type": "Scope"
              }
          ]
      }],
      "samlMetadataUrl": null
  }
  </code></pre>
  
  <p>The relevant code:</p>
  
  <pre><code>public static async Task&lt;Device&gt; GetDeviceByName(string DeviceName)
  {
      IGraphServiceDevicesCollectionPage result = await AuthHelper.GetAuthenticatedClient().Devices.Request().GetAsync();
      foreach (Device device in result)
      {
          if (device.DisplayName == DeviceName)
          {
              return device;
          }
      }
  
      return new Device();
  }
  
  static string ClientId = "{Hidden from StackOverflow}";
  public static string[] Scopes = { "User.Read", "Directory.Read.All", "Device.Read" };
  public static string TokenForUser = null;
  public static PublicClientApplication IdentityClientApp =
      new PublicClientApplication(ClientId, "https://login.microsoftonline.com/organizations");
  
  private static GraphServiceClient graphClient = null;
  
  public static GraphServiceClient GetAuthenticatedClient()
  {
      if (graphClient == null)
      {
          graphClient = new GraphServiceClient("https://graph.microsoft.com/v1.0",
              new DelegateAuthenticationProvider(async(requestMessage) =&gt;
              {
                  var token = await GetTokenForUserAsync();
                  requestMessage.Headers.Authorization =
                      new System.Net.Http.Headers.AuthenticationHeaderValue("bearer", token);
  
              }));
      }
  
      return graphClient;
  }
  
  public static async Task&lt;string&gt; GetTokenForUserAsync()
  {
      AuthenticationResult authResult;
  
      try
      {
          authResult = await IdentityClientApp
              .AcquireTokenSilentAsync(Scopes, IdentityClientApp.Users.First());
      }
      catch
      {
          authResult = await IdentityClientApp
              .AcquireTokenAsync(Scopes);
      }
  
      TokenForUser = authResult.AccessToken;
  
      return TokenForUser;
  }
  
  public static void SignOut()
  {
      foreach (var user in IdentityClientApp.Users)
      {
          IdentityClientApp.Remove(user);
      }
  
      graphClient = null;
      TokenForUser = null;
  }
  </code></pre>
  
  <p>I have been working on this for about a week and I just cannot figure out what I am doing wrong. I have looked at a ton of documents on docs.microsoft.com related to this and most examples use Web API.</p>