在.net Core中获取访问令牌

时间:2020-01-31 14:24:56

标签: c# .net-core powerbi access-token

我目前正在将Power BI嵌入式应用程序从.NET转换为.NET核心。

我用于生成令牌的旧代码如下所示:

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

但是,根据设计,.NET Core不支持UserPasswordCredential
Gunnar Peipman在最近的文章"Embedded Power BI reports with 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 个答案:

答案 0 :(得分:1)

否,recommended approach将使用ClientCredential类。

这里的想法是,让应用收集和存储用户名和密码不是正确的非交互式身份验证方法。

另请参见Microsoft identity platform and the OAuth 2.0 client credentials flowAcquiring Tokens

机密客户端应用程序的流程将是:

使用客户端凭据为应用程序本身而不是用户获取令牌。

And one more quote

在MSAL 3.x中获取令牌的模式

MSAL 3.x中的所有“获取令牌”方法都具有以下模式:

  • 从应用程序中,调用与您要使用的流相对应的AcquireTokenXXX方法,并为此流(通常是流)传递必需的参数
  • 这将返回一个命令生成器,您可以在其中使用.WithYYY方法添加可选参数
  • 然后调用ExecuteAsync()以获取身份验证结果。

这是模式:

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

example(再次是Gunnar)的操作方法:

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;
    }
}