0

I have an EventGrid Trigger in my azure function solution.

I would like to generate the trigger URL with the function key/code on the URL for subscribing to an eventgrid topic, from within the function itself. But I found no way to get the resource id of the function or to get the actual code sofar. Is it possible?

Poul K. Sørensen
  • 16,950
  • 21
  • 126
  • 283

2 Answers2

0

I believe you can use the Web Apps - List Function Secrets REST API to get the trigger URL of a function for which you know its resourceId. For reference, here is the API call as per the doc

POST https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/functions/{functionName}/listsecrets?api-version=2016-08-01

Also note that its best to use Managed Identity when making this call.

PramodValavala
  • 6,026
  • 1
  • 11
  • 30
-1

When MSI is enabled for the function i can get the resourceId of the app and ask ARM for the token.

    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)
            {

            }
        });

and then when needing to give a callback url i can do the following:

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



    }
Poul K. Sørensen
  • 16,950
  • 21
  • 126
  • 283
  • Hi, If you research the solution out, can you mark yourself's solution as the answer of this question? This will help others. :) – Cindy Pau Nov 11 '19 at 09:38