Когда для функции включен MSI, я могу получить resourceId приложения и запросить токен у ARM.
public async Task<JToken> ListHostKeys()
{
var handler = new JwtSecurityTokenHandler();
var jsonToken = handler.ReadToken(this.httpClient.DefaultRequestHeaders.Authorization.Parameter) as JwtSecurityToken;
var resourceId=jsonToken.Claims.FirstOrDefault(c => c.Type == "xms_mirid")?.Value;
var rsp = await httpClient.PostAsync($"https://management.azure.com{resourceId}/host/default/listKeys?api-version=2018-11-01", new StringContent(""));
return JToken.Parse(await rsp.Content.ReadAsStringAsync());
}
builder.Services.AddHttpClient<ArmClient>((sp, http) =>
{
try
{
var tokenProvider = new AzureServiceTokenProvider();
var accessToken = tokenProvider.GetAccessTokenAsync("https://management.azure.com/").GetAwaiter().GetResult();
http.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken);
}
catch (Exception)
{
}
});
, а затем при необходимости дать URL-адрес обратного вызова, я могу сделать следующее:
private async Task<IOBoardCollection> CreateIOBoardCollectionAsync(JToken unit)
{
//Create the collection on io-board.com
var code = "";
try
{
if (Environment.GetEnvironmentVariable("WEBSITE_HOSTNAME").Contains("azurewebsites"))
{
var keys = await armClient.ListHostKeys();
logger.LogInformation("Running on azure wbsites {keys}", keys?.ToString().Substring(10));
code = keys.SelectToken("$.systemKeys.eventgrid_extension").ToString();
}
}
catch (Exception ex)
{
logger.LogError(ex, "Failed to get code");
}
var metadata = unit.ToObject<TrackUnitProperties>();
metadata.EntityKey = context.EntityKey;
return await IOBoardClient.CreateCollectionAsync(
IOBoardClient.SubscriptionId, metadata,
$"https://{Environment.GetEnvironmentVariable("WEBSITE_HOSTNAME") ?? "io-board.eu.ngrok.io"}/runtime/webhooks/EventGrid?functionName=EventGridTrigger&code={code}");
}