Search code examples
c#microsoft-graph-apiazure-ad-b2cmicrosoft-graph-sdks

Trying to assign Azure AD B2C users to a group through external c# app using Microsoft Graph - .PostAsync Error CS1061


I have an app that is used to enrol new users into an Azure AD B2C tenant, but really struggling to get a certain feature working. If anyone has any suggestions it would be greatly appreciated!

The goal is to assign users to a group during this enrolment process, but this has proved to be a challenge. I created 4 groups through Microsoft Graph Explorer, and have the correct IDs assigned to each. I also have the following permissions for the app - API permissions in B2C for the App

Below is a screenshot of the section that I believe is the issue, followed by the code to the whole function just in case it is required (sorry it is quite long).

section of code that throws the error

    static async Task EnrollNewCompany()
    {
        var scopes = new[] { "https://graph.microsoft.com/.default" };
        var tenantId = "tenantid";
        var clientId = "Clientid";
        var clientSecret = "clientsecret";

        ClientSecretCredential clientSecretCredential = new ClientSecretCredential(tenantId, clientId, clientSecret);
        var graphClient = new GraphServiceClient(clientSecretCredential, scopes);

        Console.WriteLine("Creating a new user...");


        Console.Write("Enter display name: ");
        string displayName = Console.ReadLine()!;

        Console.Write("Enter given name: ");
        string givenName = Console.ReadLine()!;

        Console.Write("Enter surname: ");
        string surname = Console.ReadLine()!;

        Console.Write("Enter Company Phone Number: ");
        string phone = Console.ReadLine()!;

        Console.Write("Enter email address: ");
        string mail = Console.ReadLine()!;

        Console.WriteLine("Select membership level:");
        Console.WriteLine("[] Bronze");
        Console.WriteLine("[2] Silver");
        Console.WriteLine("[3] Gold");
        Console.WriteLine("[4] Admin");
        Console.Write("Please select an option: ");
        string userInput = Console.ReadLine()!;


        string groupId;
        switch (userInput)
        {
            case "1":
                groupId = "...";
                break;
            case "2":
                groupId = "...";
                break;
            case "3":
                groupId = "...";
                break;
            case "4":
                groupId = "...";
                break;
            default:
                Console.WriteLine("Invalid option. Defaulting to Bronze.");
                groupId = "BronzeGroupId"; 
                break;
        }

        string password = GeneratePassword();
        Console.WriteLine("Generated Password: " + password);

        List<string> businessPhones = new List<string> { phone };

        var requestBody = new User
        {
            DisplayName = displayName,
            GivenName = givenName,
            Surname = surname,
            BusinessPhones = businessPhones,
            Identities = new List<ObjectIdentity>
    {
        new ObjectIdentity
        {
            SignInType = "emailAddress",
            Issuer = "devB2CTennant.onmicrosoft.com",
            IssuerAssignedId = mail,
        }
    },
            PasswordProfile = new PasswordProfile
            {
                Password = password,
                ForceChangePasswordNextSignIn = false,
            },
            PasswordPolicies = "DisablePasswordExpiration",
        };

        try
        {

            var user = await graphClient.Users.PostAsync(requestBody);

            var group = await graphClient.Groups[groupId].GetAsync();

            var userDirectoryObject = new DirectoryObject { Id = user.Id };

            await graphClient.Groups[groupId].PostAsync(userDirectoryObject);

            Console.WriteLine("User created successfully");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error creating user: {ex.Message}");
        }

    }

I have looked through the Users and Groups official Microsoft documentation, but could not pinpoint an answer - https://learn.microsoft.com/en-us/graph/api/overview?view=graph-rest-1.0 (a lot of it goes over my head as I'm new to software development)

Also chatGPT is no help as it keeps suggesting outdated methods.

I have asked a few questions regarding Azure AD B2C in the last few weeks, so apologies for another, this will (hopefully) be the last.

Thanks in advance and appreciate any sort of input or ideas!


Solution

  • You need to call graphClient.Groups[groupId].Members.Ref.PostAsync to add user to a group. Not sure about the permission for adding user to a group. The doc recommends GroupMember.ReadWrite.All permission.

    var user = await graphClient.Users.PostAsync(requestBody);
    
    var group = await graphClient.Groups[groupId].GetAsync();
    
    var refRequestBody = new ReferenceCreate
    {
        OdataId = $"https://graph.microsoft.com/v1.0/directoryObjects/{user.Id}",
    };
    
    try
    {
        await graphClient.Groups[groupId].Members.Ref.PostAsync(refRequestBody);
    }
    catch(Exception ex)
    {
    }
    

    Be aware that it can take few seconds until a new user is fully provisioned, so adding a user to a group can fail with the error that the user doesn't exist. Probably some retry mechanism will help you.