Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Hosted-services / Azure

Using Microsoft.Graph.Auth to Work with Azure Active Directory (Azure AD)

5.00/5 (1 vote)
4 Oct 2023CPOL1 min read 12.6K  
Use Microsoft.Graph.Auth to work with Azure AD

Introduction

As I found out, it is not very easy to find any information on how to organize work with Azure AD through Azure Graph in the code.

The material of the article was collected in various small pieces from other articles of many sites quite a long time ago, as well as through experiments. Unfortunately, I have not saved all the useful links (please excuse me).

The final version of my experiments is below.

Background

Visual Studio, project: C# .NET Framework (Console or Web application)

Nuget package with next version required:

  • Microsoft.Graph.Auth - Version 1.0.0-preview.7
  • Microsoft.Graph - Version 4.11.0
  • Microsoft.identity.Client - Version 4.49.1
  • Microsoft.Graph.Core - Version 2.0.5

Note (!)

Microsoft.Graph - There must be a version BEFORE version 5.0.0, and Microsoft.Graph.Core BEFORE 3.0.0 because otherwise, you will get a lot of errors related to namespace references.

Install-Package Microsoft.Graph.Auth -Version 1.0.0-preview.7
Install-Package Microsoft.Graph -Version 4.11.0
Install-Package Microsoft.identity.Client -Version 4.49.1 

Using the Code

C#
using Microsoft.Graph;
using Microsoft.Graph.Auth;
using Microsoft.Identity.Client;
using System;
using System.Linq;

namespace YourProjectNameSpace
{

public class ADTestAzureManager
{
    private IConfidentialClientApplication _confidentialClientApplication; 
    private ClientCredentialProvider _clientCredentialProvider; 
    private GraphServiceClient _graphServiceClient;
    
    private string _clientId = "***";
    private string _clientSecret = "***";
    private string _tenantId = "***";

        public ADTestAzureManager()
        {
            PrepareConnection();
        }
        private void PrepareConnection()
        {
            try
            {
                _confidentialClientApplication = ConfidentialClientApplicationBuilder
                    .Create(_clientId)
                    .WithTenantId(_tenantId)
                    .WithClientSecret(_clientSecret)
                    .Build();

                _clientCredentialProvider = new ClientCredentialProvider
                                            (_confidentialClientApplication);

                _graphServiceClient = new GraphServiceClient(_clientCredentialProvider);
            }
            catch (Exception ex)
            {
                //Some logic here
            }
        }

        //With Graph no sync methods unfortunately ((
        //given the logic, in web applications, it may often be necessary 
        //to wait for the completion of an asynchronous method 
        //before moving on
        //in this case, you could use e.g. //.GetAsync().Result in the end
       
        public Group GetGroupByName(string name)
        {
            IGraphServiceGroupsCollectionPage groups = 
             _graphServiceClient.Groups.Request().Filter($"displayName eq 
             '{name.Trim()}'").Select("displayName,description,id").GetAsync().Result;

            if (groups.Count != 0)
            {
                return groups[0];
            }

            return null;
        }

        public User GetAdUserBySN(string samAccounName)
        {
            var user = _graphServiceClient.Users.Request().Filter
                       ($"SamAccounName = '{samAccounName.Trim()}'").GetAsync();
            var result = user.Result;
            return result.Count > 0 ? result[0] : null;
        }

        public User GetAdUserByPrincipalName(string upnName)
        {
            var user = _graphServiceClient.Users.Request().Filter
                       ($"UserPrincipalName = '{upnName}'").GetAsync();
            var result = user.Result;

            return result.Count > 0 ? result[0] : null;
        }

        public User GetAdUserByDisplayName(string displayName)
        {
            var user = _graphServiceClient.Users.Request().Filter
                       ($"DisplayName eq '{displayName.Trim()}'").GetAsync();
            var result = user.Result;
            return result.Count > 0 ? result[0] : null;
        }

        public bool IsUserMemberOfAzureGroup(User user, Group group)
        {
            bool result = group.Members.Any(m => m.ODataType.Equals
                          ("#microsoft.graph.user") && m.Id.Equals(user.Id));

            if (!result)
            {
                //Some additional logic here
                return false;
            }

            return result;
        }

        public bool CheckIsUserMemberOfGroup(string userId, string groupId)
        {
            IGroupMembersCollectionWithReferencesPage members = 
            _graphServiceClient.Groups[$"{groupId}"].Members.Request().GetAsync().Result;
            bool result = members.Any(m => m.ODataType.Equals
                          ("#microsoft.graph.user") && m.Id.Equals(userId));

            if (!result)
            {
                //Some additional logic here
                return false;
            }

            return result;
        }

        /// <summary>
        /// Is user is Transitive Member of group 
        /// (it can be a member of a nested group)

        public bool CheckIsUserTransitiveMemberOfGroup(string userId, string groupId)
        {

            bool result = _graphServiceClient.Groups
              [$"{groupId}"].TransitiveMembers.Request().GetAsync().Result.Any
              (m => m.ODataType.Equals("#microsoft.graph.user") && m.Id.Equals(userId));

            if (!result)
            {
                //Some additional logic here
                return false;
            }

            return result;
        }

        public bool IsUserOwnerOfAzureGroup(string userId, string groupId)
        {
            bool result = _graphServiceClient.Groups
              [$"{groupId}"].Owners.Request().GetAsync().Result.Any
              (m => m.ODataType.Equals("#microsoft.graph.user") && m.Id.Equals(userId));
            if (!result) 
            { //Some additional logic here return false; } 
            return result; 
        } 
} 
}

It should also be kept in mind that in a web application, after deployment to a real IIS, when using (.Result) for an asynchronous method, you will have a risk of going into deadlocking, so you should think in advance at the development stage about how you will avoid it.

You can find one of the articles about this problem on Stack Overflow.

Good luck!

History

  • 4th October, 2023: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)