locked
resource owner password credentials RRS feed

  • Question

  • User-590375999 posted

    Hi,

    I read this article to implement the Resource Owner Password Credentials flow ,

    https://blogs.msdn.microsoft.com/wushuai/2016/09/25/resource-owner-password-credentials-grant-in-azure-ad-oauth/

    I have following questions

    1. Where to execute this code in client application or Web API
    2. if we execute in the Server and send back to the Client. where to verify the token ( how to configure the Web API to verify the token) when the client request api method with the token
    3. Can i user more than one user credentials ( user A use his username and password , User B use his username and password etc )
    using (HttpClient client = new HttpClient())
    {
      var tokenEndpoint = @"https://login.windows.net/<tenant-id>/oauth2/token";
      var accept = "application/json";
    
      client.DefaultRequestHeaders.Add("Accept", accept);
      string postBody = @"resource=https%3A%2F%2Fgraph.microsoft.com%2F
      &client_id=<client id>
      &grant_type=password
      &username=xxx@xxx.onmicrosoft.com
      &password=<password>
      &scope=openid";
    
      using (var response = await client.PostAsync(tokenEndpoint, new StringContent(postBody, Encoding.UTF8, "application/x-www-form-urlencoded")))
      {
        if (response.IsSuccessStatusCode)
        {
          var jsonresult = JObject.Parse(await response.Content.ReadAsStringAsync());
          token = (string)jsonresult["access_token"];
        }
      }
    }

    Thursday, February 28, 2019 4:31 AM

Answers

  • User1724605321 posted

    Hi sivapooja ,

    • Where to execute this code in client application or Web API

    In anywhere server side , controller/action .

    if we execute in the Server and send back to the Client. where to verify the token ( how to configure the Web API to verify the token) when the client request api method with the token

      app.UseWindowsAzureActiveDirectoryBearerAuthentication(
                    new WindowsAzureActiveDirectoryBearerAuthenticationOptions
                    {
                        Audience = ConfigurationManager.AppSettings["ida:Audience"],
                        Tenant = ConfigurationManager.AppSettings["ida:Tenant"],
                        
                    });

    Reference code sample : https://github.com/Azure-Samples/active-directory-dotnet-webapp-webapi-openidconnect/blob/master/TodoListService/App_Start/Startup.Auth.cs#L16 

    And document : https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-v1-dotnet-webapi 

    Can i user more than one user credentials ( user A use his username and password , User B use his username and password etc )

    Since you are pass the credential from client app to your web api(seems with allow anonymous attribute) , you can use the passed credential to acquire token  , but that's not recommended  and is discouraged for both security and functionality reasons , for example you are passing the username and password to web api directly , also :

    The resource owner password credentials grant type is suitable in cases where the resource owner has a trust relationship with the client, such as the device operating system or a highly privileged application. The authorization server should take special care when enabling this grant type and only allow it when other flows are not viable.

    Also resource owner flow doesn't allow 2FA , and should be used in a native app .

    Best Regards,

    Nan Yu

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, February 28, 2019 7:56 AM

All replies

  • User1724605321 posted

    Hi sivapooja ,

    • Where to execute this code in client application or Web API

    In anywhere server side , controller/action .

    if we execute in the Server and send back to the Client. where to verify the token ( how to configure the Web API to verify the token) when the client request api method with the token

      app.UseWindowsAzureActiveDirectoryBearerAuthentication(
                    new WindowsAzureActiveDirectoryBearerAuthenticationOptions
                    {
                        Audience = ConfigurationManager.AppSettings["ida:Audience"],
                        Tenant = ConfigurationManager.AppSettings["ida:Tenant"],
                        
                    });

    Reference code sample : https://github.com/Azure-Samples/active-directory-dotnet-webapp-webapi-openidconnect/blob/master/TodoListService/App_Start/Startup.Auth.cs#L16 

    And document : https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-v1-dotnet-webapi 

    Can i user more than one user credentials ( user A use his username and password , User B use his username and password etc )

    Since you are pass the credential from client app to your web api(seems with allow anonymous attribute) , you can use the passed credential to acquire token  , but that's not recommended  and is discouraged for both security and functionality reasons , for example you are passing the username and password to web api directly , also :

    The resource owner password credentials grant type is suitable in cases where the resource owner has a trust relationship with the client, such as the device operating system or a highly privileged application. The authorization server should take special care when enabling this grant type and only allow it when other flows are not viable.

    Also resource owner flow doesn't allow 2FA , and should be used in a native app .

    Best Regards,

    Nan Yu

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, February 28, 2019 7:56 AM
  • User-590375999 posted

    Hi,

    You mean i can't use SPA,MVC client or Android using ROPC flow right? if not possible then can i suggest me the right flow.

    I know it is not secure but i have no other way since they not ready to register the client in the azure ad.

    And finally i want to ask you. 

    Which flow is suitable for my requirement

    1. web api ( secure with token )
    2. Clients (SPA, MVC, andriod ) retrieve token or any other way to consume api methods
    Thursday, February 28, 2019 9:13 AM
  • User1724605321 posted

    Hi sivapooja ,

    I know it is not secure but i have no other way since they not ready to register the client in the azure ad.

    That is the key problem . Since the client is not protected by Azure AD , you need to acquire tokens for protected apis in your web api application . In this scenario , you only have two choice :

    1. client credential flow , but it is use app's identity , there is no user identity in this scenario .
    2. Resource owner flow . But is not secure , and you should provide client secret in token request .   

     In fact , if client is not register in AAD , and you want to acquire token in web api using user's credential . The only choice is using ROPC. 

    Best Regards,

    Nan Yu

    Friday, March 1, 2019 1:46 AM
  • User-590375999 posted

    Hi,

    Our company support team registered the asp.net mvc app in azure ad under my organization

    i have tried the following code from the mvc app but i am getting "bad request" error.

     using (HttpClient client = new HttpClient())
                {
                    var tokenEndpoint = @"https://login.microsoftonline.com/xxxxxxxxx/oauth2/v2.0/token";//"
                    var accept = "application/json";
    
                    client.DefaultRequestHeaders.Add("Accept", accept);
                    string postBody = @"resource=https%3A%2F%2F*** REgistered app URL %2F
      &client_id=xxxxxx
      &grant_type=password
      &username=cxxxxx@myorgName.com
      &password=xxxxxx
      &scope=openid";
    
                    using (var response = await client.PostAsync(tokenEndpoint, new StringContent(postBody, Encoding.UTF8, "application/x-www-form-urlencoded")))
                    {
                        if (response.IsSuccessStatusCode)
                        {                        
                            var jsonresult = JObject.Parse(await response.Content.ReadAsStringAsync());
                            var toekn = (string)jsonresult["access_token"];
                        }
                    }
                }
    

    support team provide following details for the registered mvc app

    OAuth 2.0 authorization endpoint:
    
    https://login.microsoftonline.com/XXXXXXX/oauth2/v2.0/authorize 
    
    Application (client) ID:XXXXXXXX

    I suspect the url of the token end point and resource.

    Friday, March 1, 2019 2:06 AM
  • User-590375999 posted

    I tried the code with postman, i am getting the following error

    error": "invalid_grant",
        "error_description": "AADSTS50076: Due to a configuration change made by your administrator, or because you moved to a new location, you must use multi-factor authentication to access '00000003-0000-0000-c000-000000000000'.\r\nTrace ID: cff3028a-bf87-4d72-b8f5-f019078b2100\r\nCorrelation ID: cc4249aa-abbb-4e86-a429-c7dd1d187ca6\r\nTimestamp: 2019-03-01 07:35:57Z",
        "error_codes": [
            50076
        ],

    Friday, March 1, 2019 7:40 AM
  • User1724605321 posted

    Hi sivapooja,

     var tokenEndpoint = @"https://login.microsoftonline.com/xxxxxxxxx/oauth2/v2.0/token";//"

    You are working with Azure AD V2.0 endpoint :

    https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth-ropc 

    You should use scope not resource in permission request :

    POST https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token?
    
    client_id=6731de76-14a6-49ae-97bc-6eba6914391e
    &scope=user.read%20openid%20profile%20offline_access
    &client_secret=wkubdywbc2894u
    &username=MyUsername@myTenant.com
    &password=SuperS3cret
    &grant_type=password

    Best Regards,

    Nan Yu

    Monday, March 4, 2019 2:53 AM
  • User-590375999 posted

    Hi Nan Yu and Mgebhard,

    Thank you for your great help, I have tried from postman and get the "invalid grant" error, the issue is MFA is enabled, that's why i am getting the error.

    Monday, March 4, 2019 3:06 AM