From 97bacd0bb8e90d4e3da6731f816c51da9bbed96b Mon Sep 17 00:00:00 2001 From: William Petit Date: Fri, 7 Mar 2025 12:07:54 +0100 Subject: [PATCH 1/2] fix: isolated local dev environment --- .dockerignore | 4 +- Makefile | 8 +- docker-compose.yml | 103 ++++++++++++++++-- misc/compose/glauth/Dockerfile | 3 + misc/compose/glauth/glauth.cfg | 37 +++++++ misc/compose/hydra/Dockerfile | 31 ++++++ misc/compose/hydra/clients.d/oidc-test.json | 19 ++++ misc/compose/hydra/config.yml | 37 +++++++ misc/compose/hydra/docker-entrypoint.sh | 33 ++++++ misc/compose/hydra/reload-hydra-clients.sh | 12 ++ misc/compose/hydra/run-hydra.sh | 16 +++ .../init-db.d/create_database_hydra.sh | 6 + misc/docker/Dockerfile | 4 +- 13 files changed, 297 insertions(+), 16 deletions(-) create mode 100644 misc/compose/glauth/Dockerfile create mode 100644 misc/compose/glauth/glauth.cfg create mode 100644 misc/compose/hydra/Dockerfile create mode 100644 misc/compose/hydra/clients.d/oidc-test.json create mode 100644 misc/compose/hydra/config.yml create mode 100644 misc/compose/hydra/docker-entrypoint.sh create mode 100644 misc/compose/hydra/reload-hydra-clients.sh create mode 100644 misc/compose/hydra/run-hydra.sh create mode 100644 misc/compose/mariadb/init-db.d/create_database_hydra.sh diff --git a/.dockerignore b/.dockerignore index 97aaec8..653b082 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,4 +2,6 @@ /.vscode /vendor /bin -/release \ No newline at end of file +/release +/misc/compose +/tools \ No newline at end of file diff --git a/Makefile b/Makefile index e7ab84b..fc053c5 100644 --- a/Makefile +++ b/Makefile @@ -24,8 +24,8 @@ test: tidy: go mod tidy -watch: - modd +watch: tools/modd/bin/modd + tools/modd/bin/modd lint: golangci-lint run --enable-all @@ -49,6 +49,10 @@ tools/trivy/bin/trivy: mkdir -p tools/trivy/bin curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b ./tools/trivy/bin v0.47.0 +tools/modd/bin/modd: + mkdir -p tools/modd/bin + GOBIN=$(PWD)/tools/modd/bin go install github.com/cortesi/modd/cmd/modd@latest + release: release-image release-gitea release-archive: diff --git a/docker-compose.yml b/docker-compose.yml index 35b1ff3..ece7e46 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,17 +1,98 @@ -version: "2.4" services: oidc-test: - image: reg.cadoles.com/cadoles/goweb-oidc-test + build: + context: . + dockerfile: ./misc/docker/Dockerfile environment: - LOG_LEVEL=0 - - HTTP_ADDRESS=0.0.0.0:3002 - - OIDC_CLIENT_ID=local-test - - OIDC_CLIENT_SECRET=local-test - - OIDC_ISSUER_URL= - - OIDC_REDIRECT_URL=http://localhost:3002 - - OIDC_POST_LOGOUT_REDIRECT_URL=http://localhost:3002 - - OIDC_ACR_VALUES= - ports: - - 80:3002 + - HTTP_ADDRESS=0.0.0.0:8000 + - OIDC_CLIENT_ID=oidc-test + - OIDC_CLIENT_SECRET=oidc-test-123456 + - OIDC_ISSUER_URL=http://localhost:8081/ + - OIDC_REDIRECT_URL=http://localhost:8000/oauth2/callback + - OIDC_POST_LOGOUT_REDIRECT_URL=http://localhost:8000 + depends_on: + hydra: + condition: service_healthy network_mode: host + restart: unless-stopped + hydra: + build: + context: ./misc/compose/hydra + args: + - HTTP_PROXY=${HTTP_PROXY:-} + - HTTPS_PROXY=${HTTPS_PROXY:-} + - http_proxy=${http_proxy:-} + - https_proxy=${https_proxy:-} + volumes: + - ./misc/compose/hydra/config.yml:/etc/hydra/config.yml + - ./misc/compose/hydra/clients.d:/etc/hydra/clients.d + environment: + - LOG_LEAK_SENSITIVE_VALUES=true + links: + - mariadb + depends_on: + - mariadb + ports: + - 8081:4444 + healthcheck: + test: + [ + "CMD", + "wget", + "--spider", + "-q", + "http://127.0.0.1:4444/.well-known/openid-configuration", + ] + interval: 10s + timeout: 10s + retries: 3 + start_period: 10s + restart: unless-stopped + + mariadb: + image: mariadb:10.2 + environment: + MYSQL_DATABASE: hydra + MYSQL_USER: hydra + MYSQL_PASSWORD: hydra + MYSQL_ROOT_PASSWORD: hydra + TZ: Europe/Paris + volumes: + - ./misc/compose/mariadb/init-db.d:/docker-entrypoint-initdb.d/:ro + - mariadb_data:/var/lib/mysql + - /etc/localtime:/etc/localtime:ro + + glauth: + build: + context: ./misc/compose/glauth + args: + - HTTP_PROXY=${HTTP_PROXY:-} + - HTTPS_PROXY=${HTTPS_PROXY:-} + - http_proxy=${http_proxy:-} + - https_proxy=${https_proxy:-} + ports: + - 389:389 + + hydra-werther: + image: icoreru/werther:v1.2.1 + environment: + - WERTHER_LDAP_BASEDN=ou=users,dc=example,dc=com + - WERTHER_LDAP_ROLE_BASEDN=ou=groups,dc=example,dc=com + - WERTHER_DEV_MODE=True + - WERTHER_LISTEN=0.0.0.0:8080 + - WERTHER_IDENTP_HYDRA_URL=http://hydra:4445 + - WERTHER_LDAP_ENDPOINTS=glauth:389 + - WERTHER_LDAP_BINDDN=cn=admin,dc=example,dc=com + - WERTHER_LDAP_BINDPW=admin + volumes: + - ./misc/glauth/glauth.cfg:/app/config/config.cfg:ro + links: + - glauth + - hydra + ports: + - 8082:8080 + +volumes: + mariadb_data: diff --git a/misc/compose/glauth/Dockerfile b/misc/compose/glauth/Dockerfile new file mode 100644 index 0000000..eb55ed7 --- /dev/null +++ b/misc/compose/glauth/Dockerfile @@ -0,0 +1,3 @@ +FROM glauth/glauth:v2.1.0 + +COPY glauth.cfg /app/config/config.cfg \ No newline at end of file diff --git a/misc/compose/glauth/glauth.cfg b/misc/compose/glauth/glauth.cfg new file mode 100644 index 0000000..7f49ee0 --- /dev/null +++ b/misc/compose/glauth/glauth.cfg @@ -0,0 +1,37 @@ +debug = true + +[ldap] + enabled = true + listen = "0.0.0.0:389" + +[ldaps] + enabled = false + +[backend] + datastore = "config" + baseDN = "dc=example,dc=com" + +[[users]] + name = "admin" + mail = "admin@localhost" + uidnumber = 5001 + primarygroup = 5501 + passsha256 = "8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918" # admin + [[users.capabilities]] + action = "search" + object = "*" + [[users.customattributes]] + objectClass = [ "inetOrgPerson" ] + +[[users]] + name = "jdoe" + mail = "jdoe@localhost" + uidnumber = 5006 + primarygroup = 5501 + passsha256 = "d30a5f57532a603697ccbb51558fa02ccadd74a0c499fcf9d45b33863ee1582f" # jdoe + [[users.customattributes]] + objectClass = [ "inetOrgPerson" ] + +[[groups]] + name = "webapps" + gidnumber = 5501 \ No newline at end of file diff --git a/misc/compose/hydra/Dockerfile b/misc/compose/hydra/Dockerfile new file mode 100644 index 0000000..1fe9ee2 --- /dev/null +++ b/misc/compose/hydra/Dockerfile @@ -0,0 +1,31 @@ +FROM oryd/hydra:v1.11.7 + +ARG WAIT4X_VERSION="v1.1.0" + +USER root + +RUN apk add --no-cache gcompat jq + +# wait4x - utilisé pour attendre les services externes nécessaires au lancement d'hydra +RUN /bin/sh -c "wget -q -O /usr/local/bin/wait4x https://github.com/atkrad/wait4x/releases/download/$WAIT4X_VERSION/wait4x-linux-amd64" \ + && /bin/sh -c "chmod a+x /usr/local/bin/wait4x" + +COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh +RUN /bin/sh -c "chmod +x /usr/local/bin/docker-entrypoint.sh" + +COPY run-hydra.sh /usr/local/bin/run-hydra +RUN /bin/sh -c "chmod +x /usr/local/bin/run-hydra" + +RUN /bin/sh -c "mkdir -p /home/ory" \ + && /bin/sh -c "chown -R ory: /home/ory" + +COPY clients.d /etc/hydra/clients.d + +COPY reload-hydra-clients.sh /usr/local/bin/reload-hydra-clients +RUN /bin/sh -c "chmod +x /usr/local/bin/reload-hydra-clients" + +USER ory + +ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] + +CMD ["/usr/local/bin/run-hydra"] \ No newline at end of file diff --git a/misc/compose/hydra/clients.d/oidc-test.json b/misc/compose/hydra/clients.d/oidc-test.json new file mode 100644 index 0000000..59852e7 --- /dev/null +++ b/misc/compose/hydra/clients.d/oidc-test.json @@ -0,0 +1,19 @@ +{ + "client_id": "oidc-test", + "client_name": "OIDC Test", + "client_secret": "oidc-test-123456", + "grant_types": [ + "authorization_code", + "refresh_token" + ], + "jwks": {}, + "metadata": {}, + "token_endpoint_auth_method": "client_secret_post", + "post_logout_redirect_uris": ["http://localhost:8000"], + "redirect_uris": ["http://localhost:8000/oauth2/callback"], + "response_types": [ + "code" + ], + "logo_uri": "https://upload.wikimedia.org/wikipedia/commons/e/e1/Password.svg", + "scope": "openid profile email webhook" +} \ No newline at end of file diff --git a/misc/compose/hydra/config.yml b/misc/compose/hydra/config.yml new file mode 100644 index 0000000..66a259c --- /dev/null +++ b/misc/compose/hydra/config.yml @@ -0,0 +1,37 @@ +serve: + cookies: + same_site_mode: Lax + + admin: + port: 4445 + host: 0.0.0.0 + + public: + port: 4444 + host: 0.0.0.0 + +level: debug + +urls: + self: + # Adresse publique du serveur hydra + issuer: http://localhost:8081 + + # Configuration des login/consent/logout apps + consent: http://localhost:8082/auth/consent + login: http://localhost:8082/auth/login + logout: http://localhost:8082/auth/logout + +secrets: + system: + - youReallyNeedToChangeThis + +dsn: mysql://hydra:hydra@tcp(mariadb:3306)/hydra?parseTime=true + +oidc: + subject_identifiers: + supported_types: + - pairwise + - public + pairwise: + salt: youReallyNeedToChangeThis \ No newline at end of file diff --git a/misc/compose/hydra/docker-entrypoint.sh b/misc/compose/hydra/docker-entrypoint.sh new file mode 100644 index 0000000..f4088bd --- /dev/null +++ b/misc/compose/hydra/docker-entrypoint.sh @@ -0,0 +1,33 @@ +#!/bin/sh + +set -eo pipefail + + # On attend que la base de données MySQL soit disponible +/usr/local/bin/wait4x -t 60s mysql "hydra:hydra@tcp(mariadb:3306)/hydra" + +# Au premier lancement du conteneur... +if [ ! -f "$HOME/.first-run" ]; then + # On exécute les migrations Hydra + /usr/bin/hydra migrate sql --read-from-env --yes -c /etc/hydra/config.yml + + # On "marque" l'exécution + touch "$HOME/.first-run" +fi + +# Démarrage de l'interface admin d'hydra en tâche de fond +/usr/bin/hydra serve --dangerous-force-http admin -c /etc/hydra/config.yml & + +# On attend que le service hydra soit dispo +/usr/local/bin/wait4x -t 60s http http://127.0.0.1:4445 + +# Rechargement des clients OIDC +/usr/local/bin/reload-hydra-clients + +# On stoppe l'interface admin d'hydra +kill $(jobs -p) + +# On attend que le serveur Hydra soit stoppé +/usr/local/bin/wait4x -v -t 60s http http://127.0.0.1:4445 + +# On exécute la CMD Docker +exec $@ \ No newline at end of file diff --git a/misc/compose/hydra/reload-hydra-clients.sh b/misc/compose/hydra/reload-hydra-clients.sh new file mode 100644 index 0000000..6536d1b --- /dev/null +++ b/misc/compose/hydra/reload-hydra-clients.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +set -x + +HYDRA_CLIENTS_DIR=/etc/hydra/clients.d +HYDRA_ADMIN_ENDPOINT=http://127.0.0.1:4445 + +for client_file in $HYDRA_CLIENTS_DIR/*.json; do + client_id=$(basename "$client_file" | cut -f 1 -d '.') + /usr/bin/hydra clients delete --skip-tls-verify --endpoint "$HYDRA_ADMIN_ENDPOINT" "$client_id" + /usr/bin/hydra clients import --skip-tls-verify --endpoint "$HYDRA_ADMIN_ENDPOINT" "$client_file" +done \ No newline at end of file diff --git a/misc/compose/hydra/run-hydra.sh b/misc/compose/hydra/run-hydra.sh new file mode 100644 index 0000000..2caa87e --- /dev/null +++ b/misc/compose/hydra/run-hydra.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +set -xeo pipefail + +REDIRECT_URLS=$(cat /etc/hydra/clients.d/*.json | jq -n --stream 'fromstream(inputs) | (.redirect_uris + .post_logout_redirect_uris)' | jq -r '.[]') + +# À NE PAS FAIRE EN PRODUCTION ! +# Voir https://www.ory.sh/docs/hydra/debug#first-aid +export OAUTH2_EXPOSE_INTERNAL_ERRORS=true + +/usr/bin/hydra \ + serve \ + -c /etc/hydra/config.yml \ + --dangerous-force-http \ + --dangerous-allow-insecure-redirect-urls "$REDIRECT_URLS" \ + all \ No newline at end of file diff --git a/misc/compose/mariadb/init-db.d/create_database_hydra.sh b/misc/compose/mariadb/init-db.d/create_database_hydra.sh new file mode 100644 index 0000000..7069fa2 --- /dev/null +++ b/misc/compose/mariadb/init-db.d/create_database_hydra.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +set -xeo pipefail + +echo "CREATE DATABASE IF NOT EXISTS \`hydra\`;" | "${mysql[@]}" +echo "GRANT ALL ON \`hydra\`.* TO '$MYSQL_USER'@'%' ;" | "${mysql[@]}" \ No newline at end of file diff --git a/misc/docker/Dockerfile b/misc/docker/Dockerfile index 7eabaed..d0ab4dc 100644 --- a/misc/docker/Dockerfile +++ b/misc/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.19 AS build +FROM golang:1.24 AS build ARG HTTP_PROXY= ARG HTTPS_PROXY= @@ -13,7 +13,7 @@ WORKDIR /src RUN make ARCH_TARGETS=amd64 release-archive -FROM alpine as certs +FROM alpine AS certs RUN apk update && apk add ca-certificates From e2e4915e931784452033cd9aaa988624424a3a80 Mon Sep 17 00:00:00 2001 From: William Petit Date: Fri, 7 Mar 2025 12:08:53 +0100 Subject: [PATCH 2/2] fix: inject redirect_uri in oauth2 login request (#4) --- cmd/server/container.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/server/container.go b/cmd/server/container.go index 02e368f..01b4c42 100644 --- a/cmd/server/container.go +++ b/cmd/server/container.go @@ -95,6 +95,7 @@ func getServiceContainer(ctx context.Context, conf *config.Config) (*service.Con oidc.WithScopes(conf.OIDC.Scopes...), oidc.WithAcrValues(conf.OIDC.AcrValues), oidc.WithSkipIssuerCheck(conf.OIDC.SkipIssuerVerification), + oidc.WithRedirectURL(conf.OIDC.RedirectURL), )) return ctn, nil