This repository aims to debug Auth.js v5 in Docker to determine why it doesn't work with the Keycloak provider.
- Prerequisites
- Running Authentik and Keycloak in Docker with Local Webapp
- The Auth.js Docker Problem
- Testing in Docker
- Creating an Application and Provider in Authentik
- Logging into the Webapp with Authentik
- Testing Authentik in Docker with Local Webapp
- Creating a User in Keycloak
- Logging into the Webapp with Keycloak
- Testing Keycloak in Docker with Local Webapp
- Notes
- Docker
- Node.js
- Edit your
/etc/hosts
file with the following entries:127.0.0.1 keycloak.local
127.0.0.1 webapp.local
127.0.0.1 authentik.local
To run both Authentik and Keycloak in Docker, execute the following command:
docker-compose -f docker-compose-local.yml up
Follow the steps to create a user for the webapp in Keycloak and create an application and provider for the webapp in Authentik.
Then, open a second terminal window and navigate to the project directory:
cd /nextjs-auth-example
Rename .env.example
to .env.local
, replace the values for AUTH_AUTHENTIK_CLIENT_ID
and AUTH_AUTHENTIK_CLIENT_SECRET
in .env.local
, and run:
npm run dev
This will start the webapp locally.
Here is a short video demonstrating authentication working when both Authentik and Keycloak are running in Docker and the webapp is running locally. As shown, everything functions correctly with both providers. Now, let's address the issue.
local.mp4
Auth.js does not work with the Keycloak provider when running inside a Docker container.
Here is a short video of the issue.
bug.mp4
Run the following command to start the containers:
docker-compose up
This will spin up 8 containers:
- authentik: Runs the Authentik instance
- keycloak: Runs the Keycloak instance
- postgres: Runs the PostgreSQL database for Keycloak
- postgresql: Runs the PostgreSQL database for Authentik
- redis: Runs the Redis instance for Authentik
- traefik: Runs the Docker reverse proxy
- webapp: Runs the Auth.js Docker test app
- worker: Runs the Authentik worker
Once Authentik is up and running, navigate to http://authentik.local/if/flow/initial-setup/
to create your admin account.
Click "Create new application" and close the modal window. We will use the "Create with wizard" option.
Click on the "Create with wizard" button, enter webapp
in the name field, and click next
.
In the "Provider type" dropdown, select OAuth2/OIDC (Open Authorization/OpenID Connect)
and click next
.
In the "Provider configuration" section, enter the following:
- Authentication flow:
default-authentication-flow (Welcome to Authentik!)
- Authorization flow:
default-provider-authorization-explicit-consent (Authorize Application)
- Client type:
confidential
- Client ID: Copy the generated ID and paste it into the corresponding line in docker-compose.yml
- Client Secret: Copy the generated secret and paste it into the corresponding line in docker-compose.yml
- Redirect/URIs/Origin:
http://webapp.local/auth/callback/authentik
When running the webapp locally, use the following value for Redirect/URIs/Origin:
http://localhost:3000/auth/callback/authentik
Click Submit
to finish creating your application and provider. You should see the following success message:
Now, in your terminal where you ran docker-compose up
, press Ctrl + C
to stop the containers. Then, run docker-compose up
again to start the containers with the new changes.
After creating the admin
user, proceed to log into the webapp. Open http://webapp.local
in your browser and click the Sign In
button. You will be redirected to a sign-in page to select your login provider.
Click Sign in with Authentik
. This will redirect you to the Authentik login page.
Enter your credentials, and you should be redirected to the webapp, where you can see your session information.
To run Authentik in Docker, execute:
docker-compose -f docker-compose-authentik.yml up
Follow the steps to create an application and provider for the webapp in Authentik, open a second terminal window, navigate to the project directory, and rename .env.example
to .env.local
. Replace the values for AUTH_AUTHENTIK_CLIENT_ID
and AUTH_AUTHENTIK_CLIENT_SECRET
in .env.local
, and run:
npm run dev
Use the credentials you set when creating the application provider in Authentik to log in without any issues.
Once Keycloak is up and running, log into the Keycloak admin interface by visiting http://keycloak.local
in your browser.
The credentials to log into Keycloak are:
username: admin
password: admin
After logging in, select the webapp
realm from the left navigation dropdown.
Then, click Users
and on the users page, click Create new user
.
Enter the username you want to use to log into the webapp
. For simplicity, you can use admin
.
After creating the user, click the Credentials
tab and then Set password
. Enter the desired password
and password confirmation
, uncheck the temporary toggle switch, and click Save
. Confirm by clicking Save password
.
This concludes the Keycloak setup.
Log into the webapp with the username and password you set in Keycloak and click Sign In
.
The first time you log into the webapp, Keycloak will ask you to update your account information. Enter the required information and click Submit
.
Once you update your account information, you will encounter the ECONNREFUSED
error, preventing you from using the webapp.
A logger entry has been added in auth.ts with console logs to facilitate debugging in Docker.
To run Keycloak in Docker, execute:
docker-compose -f docker-compose-keycloak.yml up
Follow the steps to create a user for the webapp in Keycloak, open a second terminal window, navigate to the project directory, and rename .env.example
to .env.local
. Then run:
npm run dev
Use the credentials you set in Keycloak to log in without any issues.
The documentation specifies that you only need three environment variables:
AUTH_KEYCLOAK_ID
AUTH_KEYCLOAK_SECRET
AUTH_KEYCLOAK_ISSUER
Using only these three values works fine when running locally, but running in Docker results in an error because Auth.js does not pass the authorization URL, leading to the same ECONNREFUSED
error when clicking the sign-in button.
If you replace the Keycloak provider in auth.ts
with the following configuration, you will progress further in the authorization process in Docker, but the error persists.
Note: When running the web app locally, the Keycloak client needs to be public; otherwise, it will not work with a confidential client in Keycloak. When running Keycloak in Docker, it does not work regardless of whether the client is public or confidential.
Keycloak({
clientId: process.env.AUTH
_KEYCLOAK_ID,
clientSecret: process.env.AUTH_SECRET,
issuer: `${process.env.AUTH_KEYCLOAK_ISSUER}`,
// these are needed in order to have authjs get further in the authorization process in docker
authorization: `${process.env.AUTH_KEYCLOAK_ISSUER}/protocol/openid-connect/auth`,
wellKnown: `${process.env.AUTH_KEYCLOAK_ISSUER}/.well-known/openid-configuration`,
token: `${process.env.AUTH_KEYCLOAK_ISSUER}/protocol/openid-connect/token`,
userinfo: `${process.env.AUTH_KEYCLOAK_ISSUER}/protocol/openid-connect/userinfo`,
});
Thank you for helping debug this problem. Hopefully, we can get Auth.js to work in Docker as intended.