Получение токена доступа в ядре. net - PullRequest
0 голосов
/ 31 января 2020

В настоящее время я в процессе преобразования моего встроенного приложения Power BI из. NET в. NET core.

Мой старый код для создания токенов выглядел примерно так:

var credential = new UserPasswordCredential(Username, Password);
var authContext = new AuthenticationContext(AuthorityUrl);
var authResult = authContext.AcquireTokenSilentAsync(ResourceUrl, _applicationId).Result;

Однако, по замыслу. NET Core не поддерживает UserPasswordCredential.
Гуннар Пейпман в недавней статье «Отчеты Embedded Power BI с ASP. NET Core» использовал HTTP-запрос для решения этой проблемы, но является ли это рекомендуемым подходом?

private async Task<string> GetPowerBIAccessToken(PowerBISettings powerBISettings)
{
    using(var client = new HttpClient())
    {
        var form = new Dictionary<string, string>();
        form["grant_type"] = "password";
        form["resource"] = powerBISettings.ResourceUrl;
        form["username"] = powerBISettings.UserName;
        form["password"] = powerBISettings.Password;
        form["client_id"] = powerBISettings.ApplicationId.ToString();
        form["client_secret"] = powerBISettings.ApplicationSecret;
        form["scope"] = "openid";

        client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/x-www-form-urlencoded");

        using (var formContent = new FormUrlEncodedContent(form))
        using (var response = await client.PostAsync(powerBISettings.AuthorityUrl, formContent))
        {
            var body = await response.Content.ReadAsStringAsync();
            var jsonBody = JObject.Parse(body); 

            var errorToken = jsonBody.SelectToken("error");
            if(errorToken != null)
            {
                throw new Exception(errorToken.Value<string>());
            }

            return jsonBody.SelectToken("access_token").Value<string>();
        }
    }
}

1 Ответ

1 голос
/ 31 января 2020

Нет, рекомендуемый подход заключается в использовании ClientCredential класса.

Идея заключается в том, что для приложений для сбора и хранения имени пользователя и пароля пользователя не правильный подход для неинтерактивной аутентификации.

Также см. Платформа идентификации Microsoft и поток учетных данных клиента OAuth 2.0 и Получение токенов :

Для конфиденциальных клиентских приложений потоки будут:

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

И еще одна цитата :

Шаблон для получения токенов в MSAL 3.x

Все методы получения токенов в MSAL 3.x имеют следующий шаблон:

  • из приложения вы вызываете метод AcquireTokenXXX, соответствующий потоку, который вы хотите использовать, передавая обязательные параметры для этого потока (в общем потоке)
  • , это возвращает построитель команд, на котором вы можете добавьте необязательные параметры, используя методы .WithYYY
  • , затем вызовите ExecuteAsyn c (), чтобы получить результат аутентификации.

Вот шаблон:

    AuthenticationResult result = app.AcquireTokenXXX(mandatory-parameters)
     .WithYYYParameter(optional-parameter)
     .ExecuteAsync();

Пример (снова Гуннар), как это сделать:

public async Task<AuthenticationResult> RequestTokenAsync(
    ClaimsPrincipal claimsPrincipal,
    string authorizationCode,
    string redirectUri,
    string resource)
{
    try
    {
        var userId = claimsPrincipal.GetObjectIdentifierValue();
        var issuerValue = claimsPrincipal.GetIssuerValue();
        var authenticationContext = await CreateAuthenticationContext(claimsPrincipal)
            .ConfigureAwait(false);
        var authenticationResult = await authenticationContext.AcquireTokenByAuthorizationCodeAsync(
            authorizationCode,
            new Uri(redirectUri),
            new ClientCredential(_adOptions.ClientId, _adOptions.ClientSecret),
            resource)
            .ConfigureAwait(false);

        return authenticationResult;
    }
    catch (Exception)
    {
        throw;
    }
}
...