title: Microsoft Graph API tests - get access on behalf of user
body: <p>I have the code that creates an extension for User with Graph API (.Net Core 3.1). And I have a test project for this code. But I need to authenticate as a user in order to create and use GraphServiceClient (the user has Global Administrator Role).</p>
  
  <p>The goal is to have a working code that creates <strong>schemaExtension</strong> for <strong>User</strong>.</p>
  
  <p>Now, to create an extension the client must have Delegated permission <code>Directory.AccessAsUser.All</code> which was granted to the registered App in the portal. But since this is a Delegated permission I need to authenticate as a user (in a test code). So my options are for authentication provider:</p>
  
  <ul>
  <li>Authorization code provider</li>
  <li>On-behalf-of provider</li>
  <li>Interactive provider</li>
  </ul>
  
  <h2>For Authorization code provider:</h2>
  
  <pre><code>            List&lt;string&gt; scopes = new List&lt;string&gt; { "Directory.AccessAsUser.All" };
  
              IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
                  .Create(_appClientId.ToString())
                  .WithRedirectUri(_redirectUri)
                  .WithClientSecret(_appSecret) // or .WithCertificate(certificate)
                  .Build();
  
              AuthorizationCodeProvider authProvider = new AuthorizationCodeProvider(confidentialClientApplication, scopes);
              _graphServiceClient = new GraphServiceClient(authProvider);
  </code></pre>
  
  <p>I get an exception:</p>
  
  <blockquote>
    <p>Microsoft.Graph.Auth.AuthenticationException : Code: authenticationChallengeRequired</p>
  </blockquote>
  
  <h2>For On-behalf-of provider:</h2>
  
  <pre><code>            IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
                  .Create(_appClientId.ToString())
                  .WithRedirectUri(_redirectUri)
                  .WithClientSecret(_appSecret)
                  .Build();
  
              OnBehalfOfProvider authProvider = new OnBehalfOfProvider(confidentialClientApplication, scopes);
  
              _graphServiceClient = new GraphServiceClient(authProvider);
  </code></pre>
  
  <p>I get</p>
  
  <blockquote>
    <p>NullReferenceException</p>
  </blockquote>
  
  <p>on this line when I'm trying to actually create a schema:</p>
  
  <pre><code>SchemaExtension extension = await _graphServiceClient .SchemaExtensions.Request().AddAsync(schemaExtension);
  </code></pre>
  
  <h2>For Interactive provider:</h2>
  
  <pre><code>IPublicClientApplication publicClientApplication = PublicClientApplicationBuilder
              .Create(clientId)
              .Build();
  
  InteractiveAuthenticationProvider authProvider = new InteractiveAuthenticationProvider(publicClientApplication, scopes);
  </code></pre>
  
  <p>I get:</p>
  
  <blockquote>
    <p>Microsoft.Identity.Client.MsalClientException : Only loopback redirect uri is supported, but urn:ietf:wg:oauth:2.0:oob was found. Configure <a href="http://localhost" rel="nofollow noreferrer">http://localhost</a> or <a href="http://localhost:port" rel="nofollow noreferrer">http://localhost:port</a> both during app registration and when you create the PublicClientApplication object.</p>
  </blockquote>
  
  <p>And this last one I do not understand at all. So how can I make this delegated authentication work?</p>
  
  <h3>Addition</h3>
  
  <p>Here's the code that creates an extension but it doesn't depend on authorization:</p>
  
  <pre><code>  SchemaExtension schemaExtension = new SchemaExtension
    {
      Id = schemaName.Trim(),
      // Owner = _appClientId.ToString(),    
      Description = string.IsNullOrWhiteSpace(schemaDesc) ? string.Empty : schemaDesc.Trim(),
      TargetTypes = new List&lt;string&gt;
      {
        "User"
      },
      Properties = new List&lt;ExtensionSchemaProperty&gt;
      {
        new ExtensionSchemaProperty
        {
          Name = "isGlobalAdmin",
          Type = "Boolean"
        },
        new ExtensionSchemaProperty
        {
          Name = "isOrganizationAdmin",
          Type = "Boolean"
        }
      }
    };
  
    SchemaExtension extension = await GraphClient.SchemaExtensions.Request().AddAsync(schemaExtension); // GraphClient here === _graphServiceClient in the code above
  </code></pre>