OAuth2 Resource Owner Password Grant via API

Posted on

Problem :

I am currently building an API which requires OAuth2, but cannot find a library to use that will handle the single sign on in a native mobile app via RESTful API only. Most I’ve found only have a web popup, which has been vetoed for this project. B2C, which is currently functioning, is not capable of using ROPG. Is there a way to easily set this up with another library using C#.NET and Azure?

UPDATE:

Attempting to use B2C per Fei Xue answer below, we got to the point of getting an access token from Microsoft Graph.
In the body of the POST, we did the following:

resource=https%3A%2F%2FGraph.windows.net&client_id=[B2C Settings –
Applications –
AppId]&grant_type=password&username=rob%40[tenant].onmicrosoft.com&password=[password]&client_secret=[B2C Settings – Applications – App Key – client_secret]

Our error with the namespace was due to the usernames we were trying. This is a B2C tenant using email as the username and that was the reason for the namespace error. The only way we got past that error was to create a B2C user with the email address ending in the tenant, like so:

rob@[tenant].onmicrosoft.com

We are getting an access token now, but that token does not authenticate with our azure app service api app, which was the original goal.

What we are trying to accomplish is to send the username and password that is valid for a B2C signin and get an IdToken or Access Token that is valid for the api app. The api app connects to B2C via App Service Authentication settings configured for AAD with the Client ID and secret setup from the B2C Settings Application.

UPDATE:

Attempting to pass through the graph.windows.net token for authentication in our Azure web api, we added in the https://Graph.windows.net allowed token audience in our App Service – Authentication – Active Directory Authentication configuration.

However, passing the graph access token in the Bearer header to the API still results in

“Authorization has been denied for this request”.

Found out that if we make the Issuer Url blank like in the example below, it now accepts the Graph token!

However, this causes issues when trying to hit

https://[our_web_app].azurewebsites.net/.auth/login/aad

It goes to the common Microsoft login now. Previously it directed to our B2C sign up in policy because the Issuer Url was set to:

https://login.microsoftonline.com/[tenantname].onmicrosoft.com/v2.0/.well-known/openid-configuration?p=[B2C_SignUpIn_Policy]

In fact, if we also pull up the policy from within our app (which was working before removing the Issuer Url) to the sign in policy, we can sign in, but that returned Access Token now always comes back as Unauthorized in the web API calls.

Should the Issuer Url be left blank?

Also, since making the Issuer Url blank, the server takes much longer to respond to API calls when we send a request using a Graph access token in the Header Authorization Bearer. It went from taking about 1-2 seconds (using a valid B2C access token obtained from MSAL or the web login above) to taking about 10-15 seconds to respond that it is an authenticated request. That kind of speed is a show stopper for us. Does validating a graph call in this manner normally take this long?

Solution :

The feature is now available in preview and works pretty well:

https://docs.microsoft.com/en-us/azure/active-directory-b2c/configure-ropc

Important note: The POST url mentioned in the documentation is wrong.

https://login.microsoftonline.com/{{Aad_Tenant}}/b2c_1_ropc_auth/oauth2/v2.0/

Must be:

https://login.microsoftonline.com/{{Aad_Tenant}}/oauth2/v2.0/token?p=b2c_1_ropc_auth

The calling application must have native client enabled, otherwise you will get this error:

AADB2C90224: Resource owner flow has not been enabled for the application.

The Azure AD B2C has already support the Resource Owner Password Grant flow, you can send the HTTP request like below to using this flow:

POST: https://login.microsoftonline.com/{tenant}/oauth2/token
resource=https%3A%2F%2FGraph.windows.net&client_id={client_id}&grant_type=password&username={userName}&password={password}&client_secret={secret}

Note: this flow only work for the local accounts as social identity providers(Facebook, Google, etc) don’t support this.

Update

The token above is acquiring the token for https://graph.windows.net. To pass through the authentication of web API which protect by Azure AD, we need to specify this as the ALLOWED TOKEN AUDIENCES like figure below:
enter image description here

I work with Rob, and we did finally get the call to work with
https://login.microsoftonline.com/[tenant_ending_in_onmicrosoft.com]/oauth2/token

In the body of the POST, we did the following:

resource=https%3A%2F%2FGraph.windows.net&client_id=[B2C Settings – Applications – AppId]&grant_type=password&username=rob%40[tenant].onmicrosoft.com&password=[password]&client_secret=[B2C Settings – Applications – App Key – client_secret]

Our error with the namespace was due to the usernames we were trying. This is a B2C tenant using email as the username and that was the reason for the namespace error. The only way we got past that error was to create a B2C user with the email address ending in the tenant, like so:

rob@[tenant].onmicrosoft.com.

We are getting an access token now, but that token does not authenticate with our azure app service api app, which was the original goal. What we are trying to accomplish is to send the username and password that is valid for a B2C signin and get an IdToken or Access Token that is valid for the api app. The api app connects to B2C via App Service Authentication settings configured for AAD with the Client ID and secret setup from the B2C Settings Application.

UPDATE:
If I add ?p=[B2C SignUpIn Policy] to the POST, then we get the following error:

AADB2C90224: Resource owner flow has not been enabled for the
application.

Update to the answer from @AlexAIT.

The URL in the documentation now works for AD B2C.

https://<tenant-name>.b2clogin.com/<tenant-name>.onmicrosoft.com/B2C_1A_ROPC_Auth/oauth2/v2.0/token

https://docs.microsoft.com/en-us/azure/active-directory-b2c/add-ropc-policy?tabs=app-reg-ga&pivots=b2c-user-flow#test-the-ropc-flow

If you get the error:

AADB2C90224: Resource owner flow has not been enabled for the
application

Navigate to application -> Authentication and select Enable the following mobile and desktop flows:.

enter image description here

Wait a few minutes and then it will start to work.

Github thread:

https://github.com/MicrosoftDocs/azure-docs/issues/50330

Leave a Reply

Your email address will not be published. Required fields are marked *