DEV Community

Pablo Quezada
Pablo Quezada

Posted on

Creating a Backstage.io App with Google SSO Authentication

Before you continue

Before you continue with this article, you MUST make sure that all the Backstage.io prerequisites are installed in you local environment.

All the details can be found here: https://backstage.io/docs/getting-started/#prerequisites

Also! you can find the source of this app in my github account: https://github.com/pqzada/backstage-demo-app

Creating a new Backstage.io App

To create a new Backstage.io App you must run the following command:

npx @backstage/create-app
Enter fullscreen mode Exit fullscreen mode

This it’s going to ask you for the app name. In this exercise, we are going to use backstage-demo-app.

? Enter a name for the app [required] backstage-demo-app
Enter fullscreen mode Exit fullscreen mode

This may take a while… just be patient.

If it asks you for a database, select PostgreSQL. If don’t, that’s ok. We will configure it in the next section.

When the installation is done, you should enter the app folder and run the dev environment.

cd backstage-demo-app && yarn dev
Enter fullscreen mode Exit fullscreen mode

Database configuration

Now that our Backstage.io App is created and running, we are going to create a PostgreSQL container with docker and complete the configuration in our App.

Note: If you already have PostgreSQL installed in your local environment, you can skip the next section and go to the PostgreSQL configuration.

Creating a PostgreSQL container with Docker

To avoid having to install the database in our local environment, we are going to create a docker container with the last image available for Postgres.

Go to the root of your application and create a docker-compose.yaml file. Then paste the following code.

version: '3.8'
services:
  db:
    image: postgres:latest
    restart: always
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
    ports:
      - '5432:5432'
    volumes:
      - db:/var/lib/postgresql/data
volumes:
  db:
    driver: local
Enter fullscreen mode Exit fullscreen mode

Run the container with the following command:

docker-compose up -d
Enter fullscreen mode Exit fullscreen mode

If everything it’s ok, then the response should be like this:

Starting backstage-demo-app_db_1 ...done
Enter fullscreen mode Exit fullscreen mode

Configuration of PostgreSQL in our Backstage Demo App

Stop out Backstage Demo App (CTRL + C) and go to the root directory using the terminal. Execute the following command to start the PostgreSQL client configuration:

yarn add --cwd packages/backend pg
Enter fullscreen mode Exit fullscreen mode

Edit the app-config.yaml file and set your PostgreSQL configuration using the data from the previous steps (look in the docker-compose.yaml).

Search for the backend > database section and replace the content with the following:

database:
  client: pg
  connection:
    host: 127.0.0.1
    port: 5432
    user: postgres
    password: postgres
Enter fullscreen mode Exit fullscreen mode

Start Backstage again.

Google SSO configuration

To enable Google SSO in our Backstage Demo App we must:

  • Create OAuth credentials for our app
  • Set the OAuth credentials in our app-config.yaml file
  • Add the Google Auth Provider to the Sign In page
  • Configure Google Provider to support Sign In

Create OAuth credentials for our app

To log in using the Google SSO we need to create OAuth credentials first. If you don’t know how to do this, check this other article:

How to configure the Google Authentication Provider for Backstage.io

Set the OAuth credentials in our app-config.yaml file

Open your app-config.yaml and set the auth config. It should end up looking like this:

auth:
  environment: development
  providers:
    google:
      development:
        clientId: YOUR_CLIENT_ID
        clientSecret: YOUR_CLIENT_SECRET
Enter fullscreen mode Exit fullscreen mode

Add the Google Auth Provider to the Sign In page

Next, we must add the provider to the Sign In page. To do this, open the packages/app/src/App.tsx file, and below the last import line, add the following:

import { googleAuthApiRef } from '@backstage/core-plugin-api';
import { SignInProviderConfig, SignInPage } from '@backstage/core-components';

const googleProvider: SignInProviderConfig = {
  id: 'google-auth-provider',
  title: 'Google',
  message: 'Sign in using Google',
  apiRef: googleAuthApiRef,
};
Enter fullscreen mode Exit fullscreen mode

Then search for const app = createApp({ and below apis, add:

const app = createApp({
  apis,
  components: {
    SignInPage: props => (
      <SignInPage {...props} auto providers={['guest', googleProvider]} />
    ),
  },
  bindRoutes({ bind }) {
Enter fullscreen mode Exit fullscreen mode

At this point, we have added theSignInPage component for our Google Provider.

Configure Google Provider to support Sign In

Open the file packages/backend/src/plugins/auth.ts and change the createPluginso it looks like this:

export default async function createPlugin(
  env: PluginEnvironment,
): Promise<Router> {
  return await createRouter({
    logger: env.logger,
    config: env.config,
    database: env.database,
    discovery: env.discovery,
    tokenManager: env.tokenManager,
    providerFactories: {
      ...defaultAuthProviderFactories,
      google: providers.google.create({
        signIn: {
          resolver: async (info, ctx) => {
            const {
              profile: { email },
            } = info;

            if (!email) {
              throw new Error('User profile contained no email');
            }

            const [name] = email.split('@');

            return ctx.signInWithCatalogUser({
              entityRef: { name },
            });
          },
        },
      })
    },
  });
}
Enter fullscreen mode Exit fullscreen mode

The important here is that we added some specific logic to resolve the sign in with the Google Provider. So, take some time to understand it.

More information about the identity resolver can be found here: https://backstage.io/docs/auth/identity-resolver

Adding our user to the catalog

If we check the previous code, the login it’s going to be done with the catalog (signInWithCatalogUser), searching for an entityRefwith the name. This name is our email without the @gmail.com.

If we try to login right now we are going to get an “User not found” error like this:

https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6nrhfnkie4j8fg19ipl4.png

This is because our user doesn’t exists in the catalog. So, let’s try to add it.

In the root of our app create new folder called catalog and in the inside a new file called org.yaml. Add this content to the file:

---
apiVersion: backstage.io/v1alpha1
kind: Group
metadata:
  name: users
spec:
  type: team
  children: []
---
apiVersion: backstage.io/v1alpha1
kind: User
metadata:
  name: pqzada
spec:
  memberOf: [users]
Enter fullscreen mode Exit fullscreen mode

Then, open the app-config.yaml file and add this lines in the locations sections.

locations:
        ...
    - type: file
      target: ../../catalog/org.yaml
      rules:
        - allow: [User, Group]
Enter fullscreen mode Exit fullscreen mode

With this, we are telling our app that search in the org.yaml for users and groups.

And now if we restart our app and try to log in with our Gmail account… works OK!

https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uqizqtxfe7r9kdrf83gk.png

Any doubts? comment below!! or reach me on Twitter: https://twitter.com/pqzada

Top comments (1)

Collapse
 
riginoommen profile image
Rigin Oommen • Edited

Thanks for the great writeup. How to do SAML authentication