Search code examples
c#azureazure-cosmosdbazure-ad-b2c

Pushing Users from an Azure AD B2C into Azure Cosmos DB


As per previous questions on my account, my team and I are currently creating a Windows Forms Application in C# to allow our admin to enroll a company and all its users to our system. We can currently enroll single users to the tenant and giving them a GUID for a company ID they are separated as they should be but this currently does not give them access.

Once created in the B2C they then need to be pushed to a table in Azure Cosmos DB to allow them to log in to the system.

This is currently how a user is added to the tenant:

private async Task<string> EnrollNewUser()
{
    var scopes = new[] { "https://graph.microsoft.com/.default" };
    var tenantId = "...";
    var clientId = "...";
    var clientSecret = "...";

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

    string displayName = ESUDisplayNametxt.Text;
    string compId = esuCompIdtxt.Text;
    string givenName = ESUFirstNametxt.Text;
    string surname = ESUSurnametxt.Text;
    string phone = ESUPhoneNumtxt.Text;
    string mail = ESUEmailtxt.Text;
    string membershipLevel = ESUComboMembership.SelectedItem.ToString();

    string groupId;
    switch (membershipLevel)
    {
        case "No Membership":
            groupId = "";
            break;
        case "Bronze":
            groupId = "7118bcda-eb9d-433a-b37e-58c193c90b66";
            break;
        case "Silver":
            groupId = "ae1044e3-b711-4d97-b73a-96de89c8e005";
            break;
        case "Gold":
            groupId = "952894ab-7b7a-4f70-8b1d-ee7a8dbbd6aa";
            break;
        case "Admin":
            groupId = "048fd54e-760e-41af-8e8f-c18f02f0d58d";
            break;
        default:
            MessageBox.Show("Invalid option. Group ID left empty.");
            groupId = "";
            break;
    }

    string password = GeneratePassword();


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

    var requestBody = new User
    {
        DisplayName = displayName,
        City = compId,
        GivenName = givenName,
        Surname = surname,
        BusinessPhones = businessPhones,
        Mail = mail,
        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);

        if (!string.IsNullOrEmpty(groupId))
        {
            var refRequestBody = new ReferenceCreate
            {
                OdataId = $"https://graph.microsoft.com/v1.0/directoryObjects/{user.Id}",
            };

            await graphClient.Groups[groupId].Members.Ref.PostAsync(refRequestBody);
        }

        MessageBox.Show($"User {displayName} created successfully with password: {password}");
    }
    catch (Exception ex)
    {
        MessageBox.Show($"Error creating user: {ex.Message}");
    }
    return password;

}

Is this possible from this position or is more logic needed to make Cosmos and B2C interact with one another?


Solution

  • Note that: Azure AD B2C doesn't support storing user data in external data sources like Azure Cosmos DB natively, so this implementation is a custom solution.

    • The necessary changes should be made in your application that manages the relationship between Azure AD B2C users and Cosmos DB to ensure it targets the new data store.

    Make use of API connector:

    enter image description here

    • This will invoke your API right before the account is created in Azure AD B2C.
    • Your API should then interact with the Cosmos DB API to add the record.
    • Azure AD B2C can send all data and claims to any endpoint you specify.

    References:

    Mapping Azure AD B2C users to Azure Sql database table - Microsoft Q&A by Alfredo Revilla

    azure - How to combine AD B2C(MSAL) and CosmosDB - Stack Overflow by Jas Suri - MSFT