Search code examples
azureazure-active-directorymicrosoft-graph-api

Azure Graph API invitation returning 400 Bad Request


I have an Azure PowerShell Function App that creates a user, their resources and RBAC for them and sends invitation email to that user. It's been working unchanged for 2+ years. 3-4 weeks ago it stopped sending invitation emails. I pinpointed the culprit request and simulated it in Postman. It looks like with no apparent change on my side Invitation Graph API started sending 400 Bad Request in response. Here are snippets of my API calls. Request for Bearer Token:

curl --location --request POST 'https://login.microsoftonline.com/{{myTenantId}}/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' ' \
--header 'Cookie: brcap=0; fpc=AtYZMK7Wg2BCiTPI8GyfoR-8f7k3AQAAAJ-AsNgOAAAA; stsservicecookie=estsfd; x-ms-gateway-slice=estsfd' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'client_id={{myClientId}}' \
--data-urlencode 'client_secret={{clientSecret}}' \
--data-urlencode 'resource=https://graph.microsoft.com' \
--data-urlencode 'username={{username}}' \
--data-urlencode 'password={{userSecret}}'

This call returns 200 OK and following response:

{
    "token_type": "Bearer",
    "scope": "Directory.AccessAsUser.All User.Invite.All User.Read",
    "expires_in": "3599",
    "ext_expires_in": "3599",
    "expires_on": "1630701785",
    "not_before": "1630697885",
    "resource": "https://graph.microsoft.com",
    "access_token": "eyJ0eXAiOiJKV1QiLCJu....

Then I use this token to send a new user invitation with this request:

curl --location --request POST 'https://graph.microsoft.com/v1.0/invitations' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{token}}' \
--data-urlencode 'invitedUserEmailAddress={{userEmailAddress}}' \
--data-urlencode 'invitedUserDisplayName={{userName}}' \
--data-urlencode 'inviteRedirectUrl=https://portal.azure.com' \
--data-urlencode 'sendInvitationMessage=true'

This returns 400 Bad Request and following error details:

{"error":{"code":"UnknownError","message":"Bad Request","innerError":{"date":"2021-09-03T14:33:51","request-id":"f5cffbdd-af17-445b-bb3f-85a59bac6f31","client-request-id":"f5cffbdd-af17-445b-bb3f-85a59bac6f31"}}}

The app registration used to get the Bearer token has User.Invite.All API Permissions and the user has a Global Administrator role assigned.

I investigated this problem with Azure support but so far we have no solution


Solution

  • You are passing in url encoded variables, the documentation notes that you need to send a JSON body. I'd guess that supporting url encoded variables was a bug in the first place and it has now been fixed.

    Your second script should look like:

    curl --location --request POST 'https://graph.microsoft.com/v1.0/invitations' \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer {{token}}' \
    --data-raw '{"invitedUserEmailAddress": "{{userEmailAddress}}", "inviteRedirectUrl": "https://portal.azure.com"}'
    

    NOTE: On Windows, you might need to use double quotes and escape the JSON body when using cURL.