Search code examples
c#microsoft-graph-apidaemon

Microsoft Graph list buckets with clientsecretcredentials


I am trying to manipulate microsoft planner tasks (end goal is to create a task in a certain Scope and bucket).

I am already failing at listing a Plan or the buckets for a plan. I want to make this connection from a background service (daemon) so no interactive user login should take place. (with interactive login credentials i can make it work, but that's not what i need/want).

So i Created a new App Registration in Azure with the Api Permissions:

  • Group.Read.All (Delegated)
  • Group.ReadWrite.All (Delegated)
  • Tasks.Read (Delegated)
  • Tasks.Read.Shared (Delegated)
  • Tasks.ReadWrite (Delegated)
  • Tasks.ReadWrite.Shared (Delegated)
  • User.Read (Delegated)
  • Group.ReadWrite.All (Application)
  • Tasks.ReadWrite.All (Application)
  • User.ManageIdentities.All (Application)
  • User.ReadWrite.All (Application)

I also checked the "Allow public client flows" setting on the App registration Authentication tab.

I started by adding the ones prescribed on the official microsoft doc website about this topic. And then started adding some because i was still receiving Access Denied messages. Thus reaching this list. It should be enough according to microsoft.

Then i have this code to authenticate with Microsoft graph, giving me a graphclient instance which is successfully initialized:

private GraphServiceClient initializeTeamsGraphConnection(string TenantId, string ApplicationId, string ClientSecret)
        {
            // The client credentials flow requires that you request the
            // /.default scope, and preconfigure your permissions on the
            // app registration in Azure. An administrator must grant consent
            // to those permissions beforehand.
            var scopes = new[] { ScopeGraph };

            // Multi-tenant apps can use "common",
            // single-tenant apps must use the tenant ID from the Azure portal
            var tenantId = TenantId;

            // Values from app registration
            var clientId = ApplicationId;
            var clientSecret = ClientSecret;

            // using Azure.Identity;
            var options = new TokenCredentialOptions
            {
                AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
            };

            // https://docs.microsoft.com/dotnet/api/azure.identity.clientsecretcredential
            var clientSecretCredential = new ClientSecretCredential(
                tenantId, clientId, clientSecret, options);

            var graphClient = new GraphServiceClient(clientSecretCredential, scopes);

            return graphClient;
        }

So authentication seems to be succesful, but when i then try to list a plan using the code below:

private void CreateTask(GraphServiceClient client)
        {
            var graphTask = client.Planner.Plans["Sdonp-JNB0aInPxDcxMowZgACZ59"]
                .Request()
                .GetAsync();
            while (!graphTask.IsCompleted)
            {
                graphTask.Wait(10000);
            }
            var plans = graphTask.Result;

I get following error: 403 - Forbidden: Access is denied. You do not have permission to view this directory or page using the credentials that you supplied.

Access Permissions should be well above what is needed to do this. Any idea on what I am doing wrong?

Again this code is working because when i change authentication to some sort of interactive login type, i get this plan info no problem


Solution

  • Planner API currently supports only delegated permissions that's the reason why it returns 403 for daemon (background service).

    According to this announcement, support for application permissions is coming soon.