2

My application shows dashboard of my power bi account for all users, I am authorizing the Azure Active Directory through a dialog to get an access token. Can I hard code my credentials and get access token without using the authorization dialog. Code. It works but it is using the authorization dialog.

           var @params = new NameValueCollection
        {
            {"response_type", "code"},
            {"client_id", Properties.Settings.Default.ClientID},
            {"resource", "https://analysis.windows.net/powerbi/api"},
            {"redirect_uri", "http://localhost:13526/Redirect"}
        };


        var queryString = HttpUtility.ParseQueryString(string.Empty);
        queryString.Add(@params);

        string authorityUri = "https://login.windows.net/common/oauth2/authorize/";
        var authUri = String.Format("{0}?{1}", authorityUri, queryString);
        Response.Redirect(authUri);


        Redirect.aspx
        string redirectUri = "http://localhost:13526/Redirect";
        string authorityUri = "https://login.windows.net/common/oauth2/authorize/";

        string code = Request.Params.GetValues(0)[0];

        TokenCache TC = new TokenCache();

        AuthenticationContext AC = new AuthenticationContext(authorityUri, TC);
        ClientCredential cc = new ClientCredential
            (Properties.Settings.Default.ClientID,
            Properties.Settings.Default.ClientSecret);

        AuthenticationResult AR = AC.AcquireTokenByAuthorizationCode(code, new Uri(redirectUri), cc);

        Session[_Default.authResultString] = AR;

        Response.Redirect("/Default.aspx");
        Default.aspx
         string responseContent = string.Empty;

        System.Net.WebRequest request = System.Net.WebRequest.Create(String.Format("{0}dashboards", baseUri)) as System.Net.HttpWebRequest;
        request.Method = "GET";
        request.ContentLength = 0;
        request.Headers.Add("Authorization", String.Format("Bearer {0}", authResult.AccessToken));

        using (var response = request.GetResponse() as System.Net.HttpWebResponse)
        {
            using (var reader = new System.IO.StreamReader(response.GetResponseStream()))
            {
                responseContent = reader.ReadToEnd();
                PBIDashboards PBIDashboards = JsonConvert.DeserializeObject<PBIDashboards>(responseContent);
            }
        }
  • Can you share some code where you have tried performing the same, also some possible errors or exceptions – Rishabh Nov 28 '16 at 11:38
  • i hope it should be helps you give this answer at https://community.powerbi.com/t5/Developer/How-to-use-Power-BI-Rest-API-without-GUI-authentication-redirect/td-p/6030 – Lalji Dhameliya Nov 29 '16 at 05:19

2 Answers2

6

I did this once without using ADAL. For Power BI as well, since they don't offer application permissions, only delegated.

Note: This method won't work if the user has MFA enabled, their password has expired etc. In general you'll want to use interactive flows. You can even have a bootstrapping process where the user logs in interactively and you store the refresh token received. That refresh token can then be used in the background as long as it works.

What you need to is call the AAD token endpoint with grant_type=password. You will specify the username and password, as well as the client id, client secret and resource URI in form parameters.

Here is the function I wrote:

private async Task<string> GetAccessToken()
{
    string tokenEndpointUri = Authority + "oauth2/token";

    var content = new FormUrlEncodedContent(new []
        {
            new KeyValuePair<string, string>("grant_type", "password"),
            new KeyValuePair<string, string>("username", Username),
            new KeyValuePair<string, string>("password", Password),
            new KeyValuePair<string, string>("client_id", ClientId),
            new KeyValuePair<string, string>("client_secret", ClientSecret),
            new KeyValuePair<string, string>("resource", PowerBiResourceUri)
        }
    );

    using (var client = new HttpClient())
    {
        HttpResponseMessage res = await client.PostAsync(tokenEndpointUri, content);

        string json = await res.Content.ReadAsStringAsync();

        AzureAdTokenResponse tokenRes = JsonConvert.DeserializeObject<AzureAdTokenResponse>(json);

        return tokenRes.AccessToken;
    }
}

Authority here is https://login.microsoftonline.com/tenant-id/. Here is the response class I'm using:

class AzureAdTokenResponse
{
    [JsonProperty("access_token")]
    public string AccessToken { get; set; }
}
juunas
  • 54,244
  • 13
  • 113
  • 149
  • you are genius .I didn't thought that a web app can be used in a non-interactive way to get an access token. – sam Jan 04 '17 at 03:57
0

I hope using UserCreadential you have give username and password of azure subscription and you can get AccessToken and call your api. i hope it should helps you.

 string ResourceUrl="https://analysis.windows.net/powerbi/api";
 string ClientId=Properties.Settings.Default.ClientID;//as per your code
 AuthenticationContext authenticationContext = new AuthenticationContext(Constants.AuthString, false);
 UserCredential csr = new UserCredential("your-username", "password");
 AuthenticationResult authenticationResult = authenticationContext.AcquireToken(ResourceUrl,ClientId, usr);
 string token = authenticationResult.AccessToken;
Lalji Dhameliya
  • 1,729
  • 1
  • 17
  • 26
  • Get exception Additional information: AADSTS70002: The request body must contain the following parameter: 'client_secret or client_assertion'. Constants.AuthString=https://login.windows.net/common/oauth2/authorize/ if i change client_id to client_secret i will get exception not found application – Смирнов Дмитрий Nov 28 '16 at 14:13