Search code examples
azureloggingazure-active-directoryazure-api-managementapim

Logging API calls under AAD credentials


I have a bunch of API's running in Azure behind an APIM which require OIDC authentication by my AAD and everything works as expected but I'm wondering what would be the best way to go about monitoring/logging which user calls which API. The information is available in the JWT generated by the OIDC service of the APIM so I would expect it to be possible.

The default APIM service Analytics log some basic information for instance, without doing anything special, each call get's logged under user "Anonymous" with a randomly generated (persistent?) user id.

I can create a bunch of APIM Users and hand out the corresponding subscription keys to my AAD Users and add the keys to their headers when making the request. With this the calls get logged under their names which is exactly what I would like. The problem with this is that it doesn't seem particularly safe. What prevents the sharing of the subscription keys and/or the mismatch between AAD User credentials an APIM subscription key?

What would be the proper way to do this? Can it be done from within the APIM/AAD or do I need to use something like the Event Hubs?

Edit:

I found a solution that kinda works. By enabling Application Insights the following inbound API policy stores the name field of the JWT token as a trace.

<trace source="MyApi" severity="information">
    <message>@(context.Request.Headers.GetValueOrDefault("Authorization","No auth header").AsJwt()?.Claims.GetValueOrDefault("name", "No name field"))</message>
</trace>

Perhaps I should also add a policy if the JWT doesn't contain a field name and refuse the API call (bad request maybe).

Anyway, this sounds like a way but not the proper solution that doesn't seem like that of an unique problem.


Solution

  • You're right that it's not possible out of the box. There are two solutions I can see:

    1. The one you've found. I.e. output extra information into AppInsights log and use them to look into users.
    2. Second "not clean" solution is to pout that extra information into a header that will be sent to your backend. We don't need backend to do anything with it though, instead you can setup Azure Monitor logging to log this extra header along with every request. And then parse Azure Monitor logs (possibly with Log Analytics) to get the information you want.