Search code examples
c#asp.net-coremicrosoft-graph-api

How to get permission to Microsoft graph API dynamically?


I have written a basic C# program for testing out Microsoft graph API , but for this i configured permission for the API calls from the Azure portal , is there any better way to do this ? any Dynamic way to configure API permissions depending the API calls i add to the code rather than manually configuring them in azure portal.

GraphHandler.cs

public class GraphHandler
{
    public GraphServiceClient GraphClient { get; private set; }

    public GraphHandler(string tenantId, string clientId, string clientSecret)
    {
        GraphClient = CreateGraphClient(tenantId, clientId, clientSecret);
    }
    public GraphServiceClient CreateGraphClient(string tenantId, string clientId, string clientSecret)
    {
        var options = new TokenCredentialOptions
        {
            AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
        };

        var clientSecretCredential = new ClientSecretCredential(
            tenantId, clientId, clientSecret, options);
        var scopes = new[] { "https://graph.microsoft.com/.default" };

        return new GraphServiceClient(clientSecretCredential, scopes);
    }

    public async Task<User?> GetUser(string userPrincipalName)
    {
        return await GraphClient.Users[userPrincipalName].GetAsync();
    }

    public async Task<(IEnumerable<Site>?, IEnumerable<Site>?)> GetSharepointSites()
    {
        var sites = (await GraphClient.Sites.GetAllSites.GetAsync())?.Value;
        if(sites == null)
        {
            return (null, null);
        }

        sites.RemoveAll(x => string.IsNullOrEmpty(x.DisplayName));

        var spSites = new List<Site>();
        var oneDriveSites = new List<Site>();

        foreach (var site in sites)
        {
            if (site == null) continue;
            
            var compare = site.WebUrl?.Split(site.SiteCollection?.Hostname)[1].Split("/");
            if (compare.All(x => !string.IsNullOrEmpty(x)) || compare.Length < 1)
            {
                continue;
            }

            if (compare[1] == "sites" || string.IsNullOrEmpty(compare[1]))
                spSites.Add(site);
            else if (compare[1] == "personal")
                oneDriveSites.Add(site);
        }

        return (spSites, oneDriveSites);
    }
}

Program.cs

string tenantId = "INPUT TENANT ID";
string clientId = "INPUT CLIENT ID";
string clientSecret = "INPUT CLIENT SECRET";

var graphHandler = new GraphHandler(tenantId, clientId, clientSecret);


Console.WriteLine("Get display name of user:");
var user = await graphHandler.GetUser("mail@example.com");
Console.WriteLine(user?.DisplayName);

Console.WriteLine("Get all sharepoint sites in tenant");
var spSites = (await graphHandler.GetSharepointSites()).Item1;
foreach (var site in spSites)
{
    Console.WriteLine(site.DisplayName);
}

Console.ReadLine();

Solution

  • I have written a basic C# program for testing out Microsoft graph API , but for this i configured permission for the API calls from the Azure portal , is there any better way to do this ? any Dynamic way to configure API permissions depending the API calls i add to the code rather than manually configuring them in azure portal.

    Unfortunately, dynamically configuring Microsoft Graph API permissions isn't possible due to security threat.

    Couple of reasons behind this.

    First of all, granting access to sensitive data based on code execution creates a vulnerability. Malicious code could exploit this functionality to gain unauthorized permissions.

    Another amportnat thing is that, permissions are established during application registration in Azure AD. This allows for proper review and approval before granting access to user data.

    Altogether, there's some manual permission process however, it ensure the security layer and the proper validation process while allowing access for sensitive data.

    If you want specific user to have particular permisson you could consider delegatedpermission but still you need that permission to process manually. However, you could consider powershell script.

    Note: Please refer to this official document for additional information.