Protecting Azure API Management with Firebase Authentication
- Azure
- Firebase
- API Management
Azure API Management is Azure's solution for building API gateways. One of it's many features it's allowing us to gather all our backend endpoints and expose them behind a single entry point, taking care of the routing behind the scenes and letting us define an access policy to be applied to all of them.
In this post I'll explain how to protect an API with Google's Firebase Authentication service, defining a policy to reject all requests without a valid JWT.
If you're are just looking for the XML policy, you can skip the explanation and jump right to it.
The validate-jwt policy
API Management behavior can be customized using policies. A policy is an XML document that describes what the service needs to do when receiving a request - inbound policies, forwarding the request to the backend - backend policies, or returning the response to the sender - outbound policies. Additionally, we can define on error policies to be applied when an error is encountered while processing a request.
Since we need to validate a JWT before forwarding the request to our backends, the type of policies we are looking for are the inbound policies. Fortunately for us, there is already a built-in policy to validate an arbitrary JWT named validate-jwt. We'll need the following values to configure it:
- Firebase project ID
- The ID of your Firebase project. You can find it on the configuration section of the Firebase Console.
- Header name
- Name of the header containing the JWT. We'll use the standard
Authorizationheader on this post.
- Name of the header containing the JWT. We'll use the standard
- OpenID Connect Discovery endpoint
- An endpoint that provides the OpenID server metadata, like the public keys necessary to validate the integrity of the token. For Firebase, we need to use
https://securetoken.google.com/{projectId}/.well-known/openid-configuration. Find more details about these endpoints on the OpenID Connect Discovery specification.
- An endpoint that provides the OpenID server metadata, like the public keys necessary to validate the integrity of the token. For Firebase, we need to use
- Token audience
- The audience intended for the token. We need to use the Firebase project ID according to Firebase docs.
- Token issuer
- The issuer of the token. We need to use
https://securetoken.google.com/{projectId}according to Firebase docs.
- The issuer of the token. We need to use
Location of the Firebase project ID
Final policy
Once we finished gathering the information, our policy will end like the following.
<validate-jwt header-name="Authorization">
<openid-config url="https://securetoken.google.com/{projectId}/.well-known/openid-configuration" />
<audiences>
<audience>{projectId}</audience>
</audiences>
<issuers>
<issuer>https://securetoken.google.com/{projectId}</issuer>
</issuers>
</validate-jwt>
Now let's continue by configuring our API Management service to use it.
Configuring the policy on API Management
The next step is to configure the policy on our API Management instance. For this post, we'll be testing the policy on an API that's connected to an Azure Function, but the process it's the same no matter what kind of backends are you using.
-
Log in to the Azure Portal and navigate to your API Management instances.
-
Navigate to APIs, and then select the API you want to protect.
-
Click on All operations, and select the code view for Inbound processing.
-
Inside the XML editor, copy & paste the policy within the
<inbound>tags. Don't forget to replace the{projectId}placeholder for your actual ID 😊 (azure-api-management-authin my case). Save the changes once you finished.
Testing the policy
Now to test our work, we need a Firebase JWT. To do so I'll activate e-mail/password authentication on my Firebase project, and then a HTTP request with some test credentials I've created:
POST https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key={your-project-api-key}
With body:
{
"email": "john.doe@test.com",
"password": "12345678",
"returnSecureToken": "true"
}
This will return a response like the following, from which we need the idToken property:
{
"kind": "identitytoolkit#VerifyPasswordResponse",
"localId": "some-id",
"email": "john.doe@test.com",
"displayName": "",
"idToken": "eyJhbG...",
"registered": true,
"refreshToken": "some-token",
"expiresIn": "3600"
}
Now let's do a GET request to our new protected API, but without an authentication token:

As you can see, the request failed with a 401 Unauthorized HTTP code as expected. Now let's try adding the header Authorization with Bearer eyJhbG... as value:

Great! This time the request succeded and returned a 200 OK with the response of the underlying function. This means that our API is now correctly protected behind Firebase tokens.
Finale
Hope you find this useful, and thank you for reading. Feel free to leave your thoughts on the comments below 👇.