Автоматический вход в PowerBI и Azure AD

Я пытаюсь встроить информационные панели PowerBI в мой клиентский портал MVC. У моих клиентов нет учетных записей AAD, поэтому они не могут войти в Live, когда заходят на веб-сайт, они входят на мой веб-сайт MVC с индивидуальными полномочиями.

Я зарегистрировал свое приложение в PowerBI/AAD и получил ClientID и Secret. Я звоню в AAD и получаю код авторизации, который затем использую для получения токена подтверждения, который успешно возвращается.

Когда я использую токен доступа для получения панели управления, он постоянно отклоняется с ошибкой 403 Forbidden.

Я просмотрел все образцы от Microsoft, но они требуют запроса на вход пользователя. Я просмотрел код ADAL2.0, который ссылается на метод AcquireToken, но он устарел в ADAL3 и заменен AcquireTokenAsync с другими параметрами, и я использую его в своем примере ниже.

Вот функция для получения токена:

    protected AuthenticationResult GetAccessToken()
    {
        string pBiUser = Properties.Settings.Default.PowerBIUser;
        string pBiPwd = Properties.Settings.Default.PowerBIPwd;
        string pBiClientId = Properties.Settings.Default.PowerBIClientId;
        string pBiSecret = Properties.Settings.Default.PowerBIClientSecret;
        TokenCache TC = new TokenCache();
        ClientCredential CC = new ClientCredential(pBiClientId,pBiSecret);
        string AU = Properties.Settings.Default.PowerBIAuthority;
        Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext authenticationContext 
            = new Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext(AU, TC);
        AuthenticationResult result = authenticationContext.AcquireTokenAsync("https://analysis.windows.net/powerbi/api"
            ,CC).Result;

        if (result == null)
        {
            throw new InvalidOperationException("Failed to obtain the PowerBI token");
        }

        return result;
    }

Затем я беру токен результата и звоню. ответ получает ошибку 403:

    protected PBIDashboards GetDashboards(AuthenticationResult authResult)
    {
        PBIDashboards pbiDashboards = new PBIDashboards();
        var baseAddress = new Uri("https://api.powerbi.com");
        using (var httpClient = new System.Net.Http.HttpClient {BaseAddress = baseAddress})
        {
            httpClient.DefaultRequestHeaders.TryAddWithoutValidation("authorization",
                "Bearer " + authResult.AccessToken);
            using (**var response** = httpClient.GetAsync("v1.0/myorg/dashboards").Result)
            {
                string responseData = response.Content.ReadAsStringAsync().Result;

                //Deserialize JSON string
                pbiDashboards = JsonConvert.DeserializeObject<PBIDashboards>(responseData);

                if (pbiDashboards != null)
                {
                    var gridViewDashboards = pbiDashboards.value.Select(dashboard => new
                    {
                        Id = dashboard.id,
                        DisplayName = dashboard.displayName,
                        EmbedUrl = dashboard.embedUrl
                    });
                }
            }
        }
        return pbiDashboards;
    }

person Rob    schedule 17.03.2017    source источник
comment
Какой именно вопрос здесь? Вы пытаетесь найти способ войти в систему без пользовательского интерфейса?   -  person Shawn Tabrizi    schedule 18.03.2017


Ответы (2)


Судя по сообщению об ошибке (403), проблема связана с разрешением.

И, насколько я знаю, такого разрешения мы не можем использовать, когда получаем токен доступа с помощью потока учетных данных клиента для Power BI REST. Вы можете сослаться на разрешение для рисунка ниже:

введите здесь описание изображения

Чтобы получить токен для Power BI REST без взаимодействия с пользователем, мы можем использовать поток учетных данных владельца ресурса. И вы можете использовать стороннюю библиотеку PowerBI.Api.Client, в которой это уже реализовано.

person Fei Xue - MSFT    schedule 20.03.2017
comment
Спасибо за ответ. PowerBI.Api.Client не включает метод GetDashboards. у вас есть процесс вызовов и учетных данных для потока учетных данных владельца ресурса? - person Rob; 20.03.2017
comment
С помощью Fiddler легко получить запрос для этого потока, если вы используете стороннюю библиотеку. Или вы можете обратиться к ссылке ссылка здесь для подробной информации об этом потоке. - person Fei Xue - MSFT; 21.03.2017
comment
Мне по-прежнему не удается получить действительный токен авторизации для PowerBI с помощью ADAL 3.0. Я прошел через PowerBI.Api.Client, на который вы ссылались выше, но он не будет работать с ADAL3.0. Он использует метод AcquireToken ADAL 2.0, которого больше нет в ADAL3. Непонятно, почему это было изменено, и нет прямого способа запросить действительный токен с clientId, secretId, именем пользователя и паролем. Глядя на поток и скрипач, я не вижу подобного неинтерактивного метода получения токена. Должно быть что-то, чего мне не хватает, чтобы получить разрешение. - person Rob; 28.03.2017

После долгих исследований вы можете сделать прямой вызов AJAX, чтобы получить токен:

    private async Task<string> GetAccessToken()
    {
        string pBiUser = Properties.Settings.Default.PowerBIUser;
        string pBiPwd = Properties.Settings.Default.PowerBIPwd;
        string pBiClientId = Properties.Settings.Default.PowerBIClientId;
        string pBiSecret = Properties.Settings.Default.PowerBIClientSecret;
        string pBITenant = Properties.Settings.Default.PowerBITenantId;

        string tokenEndpointUri = "https://login.microsoftonline.com/"+pBITenant+"/oauth2/token";

        var content = new FormUrlEncodedContent(new[]
            {
        new KeyValuePair<string, string>("grant_type", "password"),
        new KeyValuePair<string, string>("username", pBiUser),
        new KeyValuePair<string, string>("password", pBiPwd),
        new KeyValuePair<string, string>("client_id", pBiClientId),
        new KeyValuePair<string, string>("client_secret", pBiSecret),
        new KeyValuePair<string, string>("resource", "https://analysis.windows.net/powerbi/api")
        });

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

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

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

            return tokenRes.AccessToken;
        }
    }

Получив строку AccessToken, вы можете вызвать запрос Dashboards.

protected PBIDashboards GetDashboards(string token)
    {
        PBIDashboards pbiDashboards = new PBIDashboards();
        var baseAddress = new Uri("https://api.powerbi.com");
        using (var httpClient = new System.Net.Http.HttpClient {BaseAddress = baseAddress})
        {
            httpClient.DefaultRequestHeaders.TryAddWithoutValidation("authorization",
                "Bearer " + token);
            using (var response = httpClient.GetAsync("v1.0/myorg/dashboards").Result)
            {
                string responseData = response.Content.ReadAsStringAsync().Result;

                //Deserialize JSON string
                pbiDashboards = JsonConvert.DeserializeObject<PBIDashboards>(responseData);

                if (pbiDashboards != null)
                {
                    var gridViewDashboards = pbiDashboards.value.Select(dashboard => new
                    {
                        Id = dashboard.id,
                        DisplayName = dashboard.displayName,
                        EmbedUrl = dashboard.embedUrl
                    });
                }
            }
        }
        return pbiDashboards;
    }

Это предоставит вам список панелей мониторинга и идентификатор панели мониторинга для вызова API PowerBI для создания встроенной страницы в Javascript. Я использовал скрытые поля ввода для хранения токена доступа и встроенного URL-адреса для перехода к вызову Javascript.

// check if the embed url was selected
var embedUrl = document.getElementById('embed').value;
if (embedUrl === "")
    return;

// get the access token.
accessToken = document.getElementById('token').value;

// Embed configuration used to describe the what and how to embed.
// This object is used when calling powerbi.embed.
// You can find more information at https://github.com/Microsoft/PowerBI-JavaScript/wiki/Embed-Configuration-Details.
var config = {
    type: 'dashboard',
    accessToken: accessToken,
    embedUrl: embedUrl
};

// Grab the reference to the div HTML element that will host the dashboard.
var dashboardContainer = document.getElementById('dashboard');

// Embed the dashboard and display it within the div container.
var dashboard = powerbi.embed(dashboardContainer, config);
person Rob    schedule 29.03.2017
comment
Привет, @Роб. Вы хотите сказать, что пропускаете этап получения кода авторизации? - person Shumii; 19.06.2017