Disable Azure AD user account using Microsoft Graph and an application client

This post shows how to enable, disable or remove Azure AD user accounts using Microsoft Graph and a client credentials client. The Microsoft Graph client uses an application scope and application client. This is also possible using a delegated client. If using an application which has no user, an application scope is used to authorize the client. Using a delegated scope requires a user and a web authentication requesting the required scope and a user consent.

History

2022-08-02 : Fixed incorrect conclusion about application client and AccountEnabled permission, feedback from Stephan van Rooij

Image: https://docs.microsoft.com/en-us/graph/overview

Microsoft Graph with an application scope can be used to update, change, edit user accounts in an Azure AD tenant. The MsGraphService class is used to implement the Graph client using OAuth client credentials. This requires a user secret or a client certificate. The client uses the default scope and no consent is required or can be used because no user is involved.

public MsGraphService(IConfiguration configuration,
	ILogger<MsGraphService> logger)
{
	_groups = configuration.GetSection("Groups").Get<List<GroupsConfiguration>>();
	_logger = logger;
	string[]? scopes = configuration.GetValue<string>("AadGraph:Scopes")?.Split(' ');
	var tenantId = configuration.GetValue<string>("AadGraph:TenantId");

	// Values from app registration
	var clientId = configuration.GetValue<string>("AadGraph:ClientId");
	var clientSecret = configuration.GetValue<string>("AadGraph:ClientSecret");

	_federatedDomainDomain = configuration.GetValue<string>("FederatedDomain");

	var options = new TokenCredentialOptions
	{
		AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
	};

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

	_graphServiceClient = new GraphServiceClient(clientSecretCredential, scopes);
}

Option 1 Update User AccountEnabled property

By setting the AccountEnabled property, a user account can be updated and can be enabled or disabled. The User.ReadWrite.All permission is required for this.

user.GivenName = userModel.FirstName;
user.Surname = userModel.LastName;
user.DisplayName = $"{userModel.FirstName} {userModel.LastName}";
user.AccountEnabled = userModel.IsActive;

await _msGraphService.UpdateUserAsync(user);

The Graph user can then be updated.

public async Task<User> UpdateUserAsync(User user)
{
	return await _graphServiceClient.Users[user.Id]
	   .Request()
	   .UpdateAsync(user);
}

Option 2 Delete User

A user can also be completely removed and deleted from the Azure AD tenant.

Disadvantages

  • User is deleted and would need to add the account again if the user account is “reactivated”

The user can be deleted using the following code:

public async Task DeleteUserAsync(string userId)
{
	await _graphServiceClient.Users[userId]
	   .Request()
	   .DeleteAsync();
}

Option 3 Remove Security groups for user and leave the account enabled

Deleting or disabling a user is normally not an option because a user might and probably does have access to further applications. After deleting a user, the user cannot be reactivated, but must sign up again. Setting AccountEnabled to false disables the whole account.

Another option instead of deleting/disabling the user is to use group memberships for access to different Azure services. When access to different services need to be removed or disabled, the user can be removed from the groups which are required to access service X or whatever. This will only work if groups are used to control the access to the different services in AAD or Office etc. The following code checks if the user has access to the explicit groups and removes the memberships if required. This works well and does not change the user settings for further services in Azure AD, or office which are outside the scope.

public async Task RemoveUserFromAllGroupMemberships(string userId)
{
	var currentGroupIds = await GetGraphUserMemberGroups(userId);
	var currentGroupIdsList = currentGroupIds.ToList();

	// Only delete specific groups we defined in this app.
	foreach (var group in _groups)
	{
		if(currentGroupIdsList.Contains(group.GroupId))
		// remove group
		await RemoveUserFromGroup(userId, group.GroupId);
		currentGroupIds.Remove(group.GroupId);
	}
}

The group membership for the user is deleted.

private async Task RemoveUserFromGroup(string userId, string groupId)
{
	try
	{
		await _graphServiceClient.Groups[groupId]
			.Members[userId]
			.Reference
			.Request()
			.DeleteAsync();
	}
	catch (Exception ex)
	{
		_logger.LogError(ex, "{Error} RemoveUserFromGroup", ex.Message);
	}
}

Disadvantages

  • Applications must use security groups for access control

For this to work, the groups must be used to force the authorization. This requires some IT management.

Links

https://docs.microsoft.com/en-us/graph/api/user-delete

https://docs.microsoft.com/en-us/graph/api/resources/groups-overview

https://docs.microsoft.com/en-us/azure/active-directory/fundamentals/users-default-permissions#compare-member-and-guest-default-permissions

https://docs.microsoft.com/en-us/graph/overview

3 comments

  1. […] Workarounds to disable Azure AD user using Microsoft Graph and an application client (Damien Bowden) […]

  2. Niranjan Singh · · Reply

    Reblogged this on Learning adventures in coding.

  3. […] Disable Azure AD user account using Microsoft Graph and an application client – Damien Bowden […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: