Search code examples
c#azureazure-ad-b2cazure-ad-msal

Why do I get a 400 - Bad Request when requesting an access token from Azure B2C using the ROPC flow?


Context

I have an Azure B2C tenant with an App Registration called App Simulator. I have a .net 8 C# console App that simulates activity on my application. To simulate users, the console app connects to Azure B2C using a dedicated User Flow that uses Resource Owner Password Credentials (ROPC) to get an access token.

I believe I followed the steps described in Microsoft's documentation.

Here is the URL I use to get the access token:

POST https://<my_tenant>.b2clogin.com/<my_tenant>.onmicrosoft.com/B2C_1_<my_ropc>/oauth2/v2.0/token

Here is the body of my request with a content type of application/x-www-form-urlencoded:

username: "<my_user>@<my_tenant>.onmicrosoft.com"
password: "<password>"
scope: "openid <my_app_registration_id>"
client_id: "<my_app_registration_id>"
response_type: "token id_token"
grant_type: "password"

The MFA is disabled for the user.

Problem

I can't get the token: I always get a 400 Bad Request status code from B2C, without any details or logs (aside from the non_parsable_oauth_error indicated by MSAL).

Here is the configuration of the App Registration:

  • oauth2AllowImplicitFlow = true

And the Granted Permissions:

Granted Permissions

Question

Why do I get a 400 - Bad Request when requesting an access token from Azure B2C using the ROPC flow in Postman?


Solution

  • The error occurs if you missed selecting valid 'Supported account type' to work with user flows while registering Azure AD B2C application.

    I created one application in my Azure B2C tenant with 'Supported account type' as below:

    enter image description here

    Initially, I too got same error when I tried to generate access token using ROPC flow via Postman for above application:

    POST https://<my_tenant>.b2clogin.com/<my_tenant>.onmicrosoft.com/B2C_1_<my_ropc>/oauth2/v2.0/token
    
    username: <my_user>@<my_tenant>.onmicrosoft.com
    password: <password>
    scope: openid <my_app_registration_id>
    client_id: <my_app_registration_id>
    response_type: token id_token
    grant_type: password
    

    Response:

    enter image description here

    To resolve the error, make sure to register the application with Supported account type as "Accounts in any identity provider or organizational directory (for authenticating users with user flows)":

    enter image description here

    Now I granted same API permissions as you in B2C app registration like this:

    enter image description here

    In App registration's Manifest, I enabled below settings to "true" as below:

    enter image description here

    Enabled mobile and desktop flows option to allow public clients:

    enter image description here

    When I replaced client_id and scope with above application ID, I got response with access token successfully like this:

    POST https://<my_tenant>.b2clogin.com/<my_tenant>.onmicrosoft.com/B2C_1_<my_ropc>/oauth2/v2.0/token
    
    username: <my_user>@<my_tenant>.onmicrosoft.com
    password: <password>
    scope: openid <my_app_registration_id>
    client_id: <my_app_registration_id>
    response_type: token id_token
    grant_type: password
    

    Response:

    enter image description here

    From your API permissions image, I observed you added profile permission that won't be present in B2C app registration created with Supported account type as "Accounts in any identity provider or organizational directory (for authenticating users with user flows)".

    To resolve your issue, create new B2C app registration with supported type allowing user flows and generate token again as I mentioned above.