Search code examples
azureazure-functionsmicrosoft-graph-apiodataazure-ad-b2c

AAD B2C - Add user to group via post to GrapAPI in Azure function


In a signup custom policy, after the user is created, I want to add him or her to a group. I tried to do it the same way I get the group membership in my signin policy, with a custom Azure function that calls the GraphAPI.

For teststing purpose, I first tried calling GraphAPI with Postman to see if it works. I got it working following the docs and came back with this query :

POST https://graph.microsoft.com/v1.0/groups/{{b2c-beneficiaire-group-id}}/members/$ref

Body: 
{
  "@odata.id": "https://graph.microsoft.com/v1.0/users/{{b2c-user-id}}"
}

And that work just fine. I get a 204 response and the user is in fact now a member of the group.

Now here's the part where I try to replicate it in my Azure function :

        var url = $"https://graph.microsoft.com/v1.0/groups/{groupId}/members/$ref)";
        var keyOdataId = "@odata.id";
        var valueODataId = $"https://graph.microsoft.com/v1.0/users/{userId}";
        var bodyObject = new List<KeyValuePair<string, string>>
        {
            new KeyValuePair<string, string>(keyOdataId, valueODataId)
        };
        var jsonData = $@"{{ ""{keyOdataId}"": ""{valueODataId}"" }}";
        var groupBody = new StringContent(jsonData, Encoding.UTF8, "application/json");
        log.LogInformation($"{url} + body:{await groupBody.ReadAsStringAsync()}");

        using (var response = await httpClient.PostAsync(url, groupBody))
        {
            log.LogInformation("HttpStatusCode=" + response.StatusCode.ToString());
            if (!response.IsSuccessStatusCode)
            {
                throw new InvalidOperationException($"{response.StatusCode} - Reason:{response.ReasonPhrase}. Content:{await response.Content.ReadAsStringAsync()}");
            }   
        }

I've tried a few variations (with HttpRequest and other things) but I always end up with an Odata error :

"BadRequest","message":"The request URI is not valid. Since the segment 'members' refers to a collection, 
this must be the last segment in the request URI or it must be followed by an function or action
that can be bound to it otherwise all intermediate segments must refer to a single resource."

From what I see it is related to the OData query (the $ref part). Do you have any idea about what do I have to do to make it work?


Solution

  • It looks like a typo in your url which ends with )

    var url = $"https://graph.microsoft.com/v1.0/groups/{groupId}/members/$ref)";