Micronaut and firebase authentication

Daniel Llewellyn
4 min readApr 8, 2020

--

Micronaut, a Java based framework for writing microservices. The framework is ideal for extending functionality of a mobile application especially when things can’t be done on the device or shouldn’t be. To do this, one of the first things we might need to do is allow our microservice to make use of users that are logged in via firebase. There are two stages to this guide, the first is getting micronaut to accept and login users that are already logged in using firebase authentication and the second is to generate custom firebase tokens and then verify them; more information about custom tokens can be found here

Setup

Assuming you do not already have a micronaut project, use the following command to create a new project

mn create-app my-app – features security-jwt

First step is to add firebase admin sdk to your gradle file

dependencies {

. implementation ‘com.google.firebase:firebase-admin:6.12.2'

}

For the next step, go to your firebase console and generate service account credentials

To generate a private key file for your service account:

In the Firebase console, open Settings > Service Accounts.

Click Generate New Private Key, then confirm by clicking Generate Key.

Securely store the JSON file containing the key. There are a number of different ways of storing and reading this file for micronaut, one approach is to store it in your micronaut resources folder and load using the following code

Accepting users logged in via firebase

Accepting existing users via firebase is fairly straight forward.

First, add this to your application.yml

micronaut:
security:
token:
jwt:
enabled: true
cookie:
enabled: true
endpoints:
logout:
enabled: true
get-allowed: true

Add the following class to your project.

What we’re doing here is using the firebase admin sdk to validate the token. By extending TokenValidator we are allowing micronaut to validate and jwt based requests to be validated by our class. You’ll also need this;

This class converts a firebase users into a custom jwt that you can consume. To test this you can use the following controller

To verify, you can get the jwt token from your existing app

Send the header to the user with postman using ‘bearer’ authentication. You should see your login information in response.

Allowing and accepting token ids

I’ll leave aside all the reasons why you might want to do this, but you can have a logged in firebase user go to your micronaut server and exchange that token with a token you generate and then in turn verify that token with your micronaut server. One reason for doing this might be if you have concepts like admin accounts you can generate a token with special claims.

The first step is to generate a custom token by firebase. Here’s an example controller to do this:

This code required authentication to run, and thereafter will generate a custom token that a user can use with firebase services.

Try to run this with a real firebase users jwt use the link below and print out the token, then create a postman request to call /login/logmein. Your response is another jw token. Keep this as you’ll need it later.

Now, what were going to make work next is for us to use that token in order to call the controller we implemented in step 1 (/authenticated/verify)

First we need to get the public keys that were used to generate our custom certificate. To do this, look in your firebase service account JSON file that you created in the setup step. Inside this file you have a link called

client_x509_cert_url

Go to this link and you’ll see a JSON blob. In mine there are two certificates starting with — -begin certificate--- and ending with n-----END CERTIFICATE-----\n.

We need to convert these certificates into public keys. Use the following python script, replacing certificate text with your own text.

from cryptography.x509 import load_pem_x509_certificate
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization

cert_str = '-----BEGIN CERTIFICATE-----\n(All of your certificate copied and pasted here)+\n-----END CERTIFICATE-----\n'
cert_obj = load_pem_x509_certificate(str.encode(cert_str), default_backend())

public_key=cert_obj.public_key()


print(public_key.public_bytes(serialization.Encoding.PEM, serialization.PublicFormat.SubjectPublicKeyInfo))

You’ll need to do this for each certificate (I have two), create a new class that looks like this (be sure to give unique names instead of generator)

Rebuild, rerun and retry the previously generated jw token with your verify command and voila, you have successfully integrated firebase and micronaut.

--

--

Responses (1)