Skip to content
This repository has been archived by the owner on Jul 5, 2023. It is now read-only.

acquireToken by providing clientId, clientSecret, username, password #100

Closed
wants to merge 5 commits into from

Conversation

zzeekk
Copy link

@zzeekk zzeekk commented Aug 14, 2016

I tried to use the PowerBI API with non-interactive authentication and the following acquireToken call:
token = authContext.acquireToken(resourceUri, clientId, username, pw, null).get()
This results in the following error:
com.microsoft.aad.adal4j.AuthenticationException: {"error_description":"AADSTS90014: The request body must contain the following parameter: 'client_secret or client_assertion'.\r\nTrace ID: dd5f457c-9bd0-4f3f-a999-74f9c539f544\r\nCorrelation ID: 961ed1cc-fea3-4217-88bb-f361b9b2e267\r\nTimestamp: 2016-08-14 06:57:16Z","error":"invalid_request"}

Currently an acquireToken method with parameters clientId, clientSecret, username, password is missing. This pull-request fixes this and makes it possible to get a Token which can be used with PowerBI API.

@msftclas
Copy link

Hi @zzeekk, I'm your friendly neighborhood Microsoft Pull Request Bot (You can call me MSBOT). Thanks for your contribution!

In order for us to evaluate and accept your PR, we ask that you sign a contribution license agreement. It's all electronic and will take just minutes. I promise there's no faxing. https://cla.microsoft.com.

TTYL, MSBOT;

@msftclas
Copy link

@zzeekk, Thanks for signing the contribution license agreement so quickly! Actual humans will now validate the agreement and then evaluate the PR.

Thanks, MSBOT;

@mparker
Copy link

mparker commented Jan 3, 2017

Will someone with write access please pull this? This fix is required for any AAD web application that needs app+user auth, not just PowerBI.

@M3lkior
Copy link

M3lkior commented Jan 31, 2017

+1

@psignoret
Copy link
Contributor

In general, the practice of collecting a user's username and password should be (and can be, in almost every case) avoided. Not only is it a security risk, but it will severely limit the capabilities that your app can offer. See AzureAD/azure-activedirectory-library-for-dotnet#482 for more discussion on the topic.

The Resource Owner Password Credentials Grant flow for confidential clients (which is what you are trying to invoke with a client ID, client secret, username and password) is not a supported flow with Azure AD. (It will soon stop working on the service side, even if you try manually craft the request.) This flow is only supported for apps registered as native clients (i.e. public clients, in OAuth 2.0 terminology), which don't have client credentials. (Again: you don't want to do that in a web app.)

If you are building a web app (e.g. @mparker, @M3lkior), then you would want to use the Authorization Code Grant flow, which starts by redirecting the user to the authorization endpoint (e.g. as constructed in the web app sample by getRedirectUrl()), and then using acquireTokenByAuthorizationCode to exchange the returned authorization code for the ID Token, Access Token and Refresh Token. The resulting Access Token will will be in the app+user context, and can be used against Power BI.

@M3lkior
Copy link

M3lkior commented Feb 1, 2017

@psignoret, In my case, i'm using Adal4j with Spring Security to provide an authentification endpoint for my users.
SO I can not use the Authorization Code Grant flow i think.

My workflow :

  • A front end app use my backend REST endpoint to authenticate an user
  • this rest endpoint, based on spring security, try to authenticate the user thanks to Adal4j, by passing his username & password
  • if Adal4j authentication is done, i call the Azure Graph API to get more details about my user
  • and finally, my backend generate a JWT token based on authentication result, provide to the client APP

@zzeekk
Copy link
Author

zzeekk commented Feb 2, 2017

Finally some traffic on this thread :-)

@psignoret: my use case is a service on azure, which collects sensor data and pushes it to PowerBI real-time. There is no user on the way... but PowerBI needs clientAssertion & user. How can i authenticate against PowerBI-API as a service?

@psignoret
Copy link
Contributor

@M3lkior, can you tell me more about your front-end app? What platforms is it running on? (Native client on desktop, on mobile, in browser (i.e. JavaScrip SPA), etc.)

@M3lkior
Copy link

M3lkior commented Feb 7, 2017

My front-end app is running on node.js (express & vue.js), but Azure AD is consumed by my backend which is based on Spring / running under tomcat8

@psignoret
Copy link
Contributor

@zzeekk: Ah, this is similar to the scenario with the Dynamics CRM Online API, described in AzureAD/azure-activedirectory-library-for-dotnet#482. In the comment that link will take you to, I describe the different options, and conclude that the only way to use that API from a service which does not ever have user interaction is, in fact, to use a user account as a service account.

The issue stems from the fact that the Power BI REST API does not expose any app-only permissions, and does not understand the concept of a an application authenticating as itself (as opposed to in the context of a signed-in user).

The only two ways I know of to work around this limitation are a) to generate and access token and refresh token via interactive authentication, and then use the refresh token to get fresh access and refresh tokens, and b) to use a user account as a service account. The main issue with the former approach is that the app needs to run more or less continuously to ensure the refresh token doesn't expire. To do the latter:

  1. Register a native client application with the necessary permissions to Power BI:

    Registering a native client application in the Azure portal

    Selecting delegated permissions to Power BI Service in the Azure portal

  2. Use the "Grant Permissions" button to consent to the app on behalf of users:

    Granting permissions in the Azure portal

  3. Create a new cloud-only user (e.g. power-bi-service-account@contoso.onmicrosoft.com). Generate and set a strong random password for this user. Set the password to never expire (or leave it with an expiry, but set a reminder somewhere). This user's password is a secret, equivalent to the client secret when you register an app. Keep it secret, keep it safe. (E.g. don't check it in to GitHub, avoid putting it in code at all, etc.)

  4. In your service code, use the ADAL method for public clients to obtain the access token to Power BI:

     public Future<AuthenticationResult> acquireToken(
         final String resource,
         final String clientId,
         final String username,
         final String password,
         final AuthenticationCallback callback)
    

@fatmanmclone90
Copy link

Does anyone know if this is going to be merged still?

@psignoret
Copy link
Contributor

psignoret commented Mar 9, 2017

@fatmanmclone90 It is highly unlikely that this pull request will be merged, since it invokes a flow that is not supported by Azure AD. (See the conversation above for more detail.) I'll make sure someone from that team passes by to give a definitive answer and closes the PR.

@kpanwar
Copy link
Contributor

kpanwar commented Mar 12, 2017

@psignoret is correct. This flow will actually be disabled on the service side in the near future.

@westleyMS
Copy link

@kpanwar is there a resource that lists the supported variations of the flows etc? In the main OAuth flow docs it seems they don't call out which clients it works for (public / confidential).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants