For future projects and out of personal curiosity, I want to explore authentication management platforms beyond Keycloak, which I’ve already used. In this post, I’ll take a look at Casdoor, an Identity and Access Management (IAM) and Single Sign-On (SSO) solution with a user-friendly UI, built in Go 😎. I chose Casdoor for its extensive third-party login support, customizable login themes, and a unique payment integration feature. Let’s see how it performs! 🚀

Testing: Docker implementation

For this test, I set up a simple Docker Compose configuration with three services:

  • Casdoor
  • MySQL – the database used by Casdoor
  • Grafana – for integration testing

Project structure

docker-compose.yml
casdoor
 └── conf
    └── app.conf

You will need to create the folder for the Casdoor config. Download the template from here: https://github.com/casdoor/casdoor/blob/master/conf/app.conf and change the following parameters:

driverName = mysql
dataSourceName = casdoor:casdoorpassword@tcp(casdoor_db:3306)/
dbName = casdoor

Docker Compose

docker-compose
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
services:
  casdoor:
    image: casbin/casdoor:latest
    container_name: casdoor
    restart: unless-stopped
    networks:
      - app_network
    ports:
      - "8000:8000"
    environment:
      - RUNNING_IN_DOCKER=true
    depends_on:
      - casdoor_db
    volumes:
      - casdoor_data:/data
      - ./casdoor/conf/app.conf:/conf/app.conf

  casdoor_db:
    image: mysql:5.7
    container_name: casdoor_db
    restart: unless-stopped
    networks:
      - app_network
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: rootpassword
      MYSQL_DATABASE: casdoor
      MYSQL_USER: casdoor
      MYSQL_PASSWORD: casdoorpassword
    volumes:
      - mysql_data:/var/lib/mysql

  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    restart: unless-stopped
    networks:
      - app_network
    ports:
      - "3000:3000"
    environment:
      - GF_AUTH_GENERIC_OAUTH_ENABLED=true
      - GF_AUTH_GENERIC_OAUTH_NAME=Casdoor
      - GF_AUTH_GENERIC_OAUTH_CLIENT_ID=54e2a65731f59d91ff59
      - GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET=f235072f4eec97573b00d35b56a4e543b059a9f7
      - GF_AUTH_GENERIC_OAUTH_AUTH_URL=http://localhost:8000/login/oauth/authorize
      - GF_AUTH_GENERIC_OAUTH_TOKEN_URL=http://casdoor:8000/api/login/oauth/access_token
      - GF_AUTH_GENERIC_OAUTH_API_URL=http://localhost:8000/api/userinfo
      - GF_AUTH_GENERIC_OAUTH_ORG_ATTRIBUTE_PATH=groups
      - GF_AUTH_GENERIC_OAUTH_ORG_MAPPING=*:*:Editor
      - GF_SERVER_ROOT_URL=http://localhost:3000
    volumes:
      - grafana_data:/var/lib/grafana

volumes:
  grafana_data:
  casdoor_data:
  mysql_data:
  
networks:
  app_network:
    driver: bridge

Setting Up Casdoor Authentication with Grafana Using Docker Compose

1. Login into Casdoor

The first step is to access http://localhost:8000 and log in with the admin account:

user: admin
password: 123
2. Creating an Organization in Casdoor

Navigate to Organizations and create a new one named demo, keeping the default settings.

creating organization casdoor

3. Setting Up an Application for Grafana in Casdoor

Create a new application in Casdoor with the following configurations:

  Name: Grafana
  Display Name: Grafana
  Organization: demo
  Client ID: 54e2a65731f59d91ff59 (Matches GF_AUTH_GENERIC_OAUTH_CLIENT_ID in docker-compose)
  Client Secret: f235072f4eec97573b00d35b56a4e543b059a9f7 (Matches GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET)
  Redirect URLs: http://localhost:3000/login/generic_oauth
  Signup Items: Remove required fields for Display Name, Confirm, Phone, Agreement. Set Email Rule to No Verification

creating application casdoor

4. Logging into Grafana with Casdoor

Open http://localhost:3000 in a private browser session.
Click Sign in with Casdoor
You should now be logged in successfully, but the user is assigned to Grafana’s default Main Org.

grafana login

5. Assigning Users to Different Organizations in Grafana

By default, all users are placed in Main Org in Grafana.

grafana main org

If you want to automatically assign users to specific Grafana organizations, Casdoor’s Groups feature can help.

  1. Configure Grafana to Use Groups
    Has you remember we added the environment variables in the docker compose:
- GF_AUTH_GENERIC_OAUTH_ORG_ATTRIBUTE_PATH=groups
- GF_AUTH_GENERIC_OAUTH_ORG_MAPPING=*:*:Viewer

This will map users in Casdoor groups to organizations in Grafana.

  1. Create a Group and map users in Casdoor
    To assign users to a Grafana organization named demo org:

    1. In Casdoor go to: User Management > Groups
      Create a new group named demo org

    casdoor create group

    1. In Casdoor go to: User Management > Users
      Select a user, and scroll down to Groups and assign the user to the demo org group casdoor user group
6. The Manual Step! Creating the Organization in Grafana

Since Grafana does not automatically create organizations from OAuth data, you must create it manually:
Access http://localhost:3000 and log in as the admin user:

user: admin  
password: admin  

In Grafana navigate to: Home > Administration > General > Organizations and create a new organization called demo org:

grafana add org

Logout from admin and log in again with the user assigned to the demo org group.
The user should now have access to demo org inside Grafana

grafana org

7. Automating Organization Creation in Grafana via API

To avoid manually creating the organization, you can use Grafana’s API:

curl -X POST -H "Content-Type: application/json" -d '{"name":"demo org"}' http://admin:admin@localhost:3000/api/orgs
8. Can Casdoor Automate This?

Casdoor supports webhooks, which send JSON payloads when specific events occur. However, currently, the webhook payload is not customizable, meaning we cannot include the “name” field required for the Grafana API.

Possible Workarounds:

  • Suggest an enhancement on Casdoor’s GitHub to allow custom payloads
  • Create a backend script to listen for Casdoor events and format the request properly

Final Thoughts

With this setup, Casdoor can manage authentication for Grafana, and users can be assigned to specific organizations. While a manual step is still needed, automating it with Grafana’s API is a possible workaround. Future improvements in Casdoor’s webhook flexibility could make this process fully automated.