Nextcloud se connectait et echouait a la deconnexion — « invalid redirect uri ». Keycloak valide ces URI SEPAREMENT des URI de rappel, et aucun des quatre clients ne declarait l'attribut ; Nextcloud etait seulement le seul a en envoyer une. post.logout.redirect.uris derivee de web_origins, qui porte deja l'URL de base du service. Posee par l'API : attributes est une map, et kcadm -s sur une map accepte sans ecrire (meme leçon que smtpServer ce matin). Relu apres ecriture. Le second passage a revele un defaut de l'heure precedente : la tache de journalisation se declarait changed a chaque deploiement — Jinja rendait True et 1209600 en CHAINES, la comparaison au reel ne pouvait aboutir. Compose en une seule expression, types natifs. Deux passages a changed=0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
56 lines
2.4 KiB
YAML
56 lines
2.4 KiB
YAML
---
|
|
# URI de retour APRES DECONNEXION, par client.
|
|
#
|
|
# Keycloak les valide separement des URI de rappel : un client peut donc se connecter
|
|
# parfaitement et echouer a la deconnexion, sur un « We are sorry… invalid redirect uri »
|
|
# qui ne dit pas de quelle liste il parle. Constate le 2026-08-08 sur Nextcloud — et
|
|
# AUCUN des quatre clients ne declarait cet attribut ; Nextcloud etait seulement le seul
|
|
# a envoyer une URI de retour.
|
|
#
|
|
# DERIVEE de `web_origins`, qui porte deja l'URL de base du service : la connaissance
|
|
# existe, il n'y a pas a la reecrire. `/*` couvre la page d'accueil et les chemins de
|
|
# retour que chaque application choisit.
|
|
#
|
|
# Par l'API et non `kcadm -s` : `attributes` est une MAP, et sur une map kcadm accepte
|
|
# la commande, sort en succes et n'ecrit rien (mesure du meme jour sur `smtpServer`).
|
|
# On relit systematiquement apres avoir pose.
|
|
|
|
- name: Lire les clients du realm
|
|
ansible.builtin.uri:
|
|
url: "http://localhost:8080/admin/realms/{{ serveur_keycloak_realm }}/clients"
|
|
headers:
|
|
Authorization: "Bearer {{ serveur_keycloak_pol_jeton.json.access_token }}"
|
|
register: serveur_keycloak_clients_actuels
|
|
no_log: true
|
|
|
|
- name: Composer les URI de déconnexion attendues
|
|
ansible.builtin.set_fact:
|
|
serveur_keycloak_deconnexion: >-
|
|
{{ dict(serveur_keycloak_clients | map(attribute='clientId') | list
|
|
| zip(serveur_keycloak_clients
|
|
| map(attribute='web_origins')
|
|
| map('map', 'regex_replace', '/?$', '/*')
|
|
| map('join', '##') | list)) }}
|
|
|
|
- name: Déclarer l'URI de retour après déconnexion
|
|
ansible.builtin.uri:
|
|
url: >-
|
|
http://localhost:8080/admin/realms/{{ serveur_keycloak_realm
|
|
}}/clients/{{ item.id }}
|
|
method: PUT
|
|
status_code: [204]
|
|
headers:
|
|
Authorization: "Bearer {{ serveur_keycloak_pol_jeton.json.access_token }}"
|
|
body_format: json
|
|
body: >-
|
|
{{ item | combine({'attributes': (item.attributes | default({}))
|
|
| combine({'post.logout.redirect.uris': serveur_keycloak_deconnexion[item.clientId]})}) }}
|
|
loop: "{{ serveur_keycloak_clients_actuels.json }}"
|
|
loop_control:
|
|
label: "{{ item.clientId }}"
|
|
no_log: true
|
|
changed_when: true
|
|
when:
|
|
- item.clientId in serveur_keycloak_deconnexion
|
|
- (item.attributes | default({})).get('post.logout.redirect.uris', '')
|
|
!= serveur_keycloak_deconnexion[item.clientId]
|