是否可以从 azure 函数中为 EventGrid 生成 TriggerUrl?
Is it possible to generate TriggerUrl for EventGrid from within the azure function?
我的 azure 函数解决方案中有一个 EventGrid 触发器。
我想在 URL 上使用函数 key/code 生成触发器 URL,以便从函数本身内部订阅事件网格主题。但是到目前为止,我找不到获取函数资源 ID 或获取实际代码的方法。可能吗?
我相信您可以使用 Web Apps - List Function Secrets REST API 获取您知道其 resourceId
的函数的触发器 URL。作为参考,这里是 API 根据文档
调用
POST https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/functions/{functionName}/listsecrets?api-version=2016-08-01
另请注意,进行此调用时最好使用 Managed Identity。
当为该功能启用 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}");
}
我的 azure 函数解决方案中有一个 EventGrid 触发器。
我想在 URL 上使用函数 key/code 生成触发器 URL,以便从函数本身内部订阅事件网格主题。但是到目前为止,我找不到获取函数资源 ID 或获取实际代码的方法。可能吗?
我相信您可以使用 Web Apps - List Function Secrets REST API 获取您知道其 resourceId
的函数的触发器 URL。作为参考,这里是 API 根据文档
POST https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/functions/{functionName}/listsecrets?api-version=2016-08-01
另请注意,进行此调用时最好使用 Managed Identity。
当为该功能启用 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}");
}