我目前正在将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>();
}
}
}
答案 0 :(得分:1)
否,recommended approach将使用ClientCredential
类。
这里的想法是,让应用收集和存储用户名和密码不是正确的非交互式身份验证方法。
另请参见Microsoft identity platform and the OAuth 2.0 client credentials flow和Acquiring Tokens:
机密客户端应用程序的流程将是:
使用客户端凭据为应用程序本身而不是用户获取令牌。
在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;
}
}