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
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)
{
}
}
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)
{
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)
{
return false;
}
return result;
}
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)
{
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)
{
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