Je cherche à améliorer notre posture de sécurité, et cela implique que nous devons éviter d’utiliser des identifiants secrets autant que possible.
Malheureusement, le plugin OIDC nécessitait un identifiant secret client pour atteindre le point de terminaison /userinfo, et je n’ai pas pu configurer mon forum avec celui-ci activé.
Heureusement, la spécification OIDC est en fait définie d’une manière qui ne nécessite pas l’utilisation de jetons secrets.
Si nous nous en tenons au flux id_token, l’IdP nous enverra toutes les informations dont nous avons besoin pour authentifier un utilisateur sans avoir à recontacter l’IdP.
C’est sécurisé car la redirection est configurée dans l’IdP, et nous n’avons pas à nous soucier que le jeton porteur soit transmis à la mauvaise destination.
J’ai créé un patch pour le plugin OIDC afin de prendre en charge le flux id_token et j’ai soumis une pull request ici :
La PR n’est pas tout à fait complète car elle nécessite toujours des tests unitaires, mais elle est pratiquement terminée et j’ai confirmé que cela fonctionne correctement avec Azure AD (Entra ID).
Pour référence, voici la documentation du plugin OIDC :
Je pense que ce que vous décrivez ici est le flux implicite d’OpenID Connect, qui fonctionne sans aucune communication serveur à serveur, et n’a donc pas besoin de secret partagé. Au lieu de cela, toutes les informations sont transmises via les redirections HTTP, et le jeton d’identification est vérifié cryptographiquement à l’aide des clés publiques du document de découverte.
C’est bien, et je pense que c’est une demande de fonctionnalité valide. Mais c’est un système très différent de notre plugin actuel, qui utilise le flux de code d’autorisation. Ce flux utilise une communication serveur à serveur avec un secret partagé, et donc aucune vérification cryptographique de l’id_token n’est nécessaire. C’est plus simple à certains égards, mais plus complexe à d’autres.
Important : nous ne pouvons pas simplement modifier l’implémentation par défaut du plugin. Les sites qui utilisent le flux de code d’autorisation doivent continuer à l’utiliser. Je crois me souvenir que de nombreux fournisseurs d’identité ne prennent même pas en charge le flux implicite.
Je pense donc qu’il y a deux voies à suivre ici :
Nous ajoutons la prise en charge du “flux implicite” dans le plugin OIDC, mais en tant qu’option opt-in. Je pense qu’il est peu probable que nous acceptions une PR qui introduise la gemme openid-connect comme dépendance de Discourse core, elle devrait donc être implémentée dans notre stratégie actuelle.
Le plugin discourse-lti (intégration d’outils d’apprentissage) peut être une source d’inspiration utile, car le protocole LTI est basé sur le flux implicite OIDC. La logique de décodage de l’id_token se trouve ici.
ou alternativement
Vous créez le flux implicite en tant que plugin entièrement nouveau. Dans ce cas, vous seriez libre de faire ce que vous voulez en termes d’implémentation (mais vous devriez également le maintenir vous-même).
Il convient également de noter que le « flux implicite » OIDC augmente la surface d’attaque pour les attaques CSRF et l’exposition des jetons :
Je pense qu’il peut encore avoir du sens dans certaines situations. Mais il semble que le flux de code d’autorisation (par défaut dans Discourse) avec PKCE (facultatif dans Discourse) soit la manière la plus recommandée d’utiliser OIDC.
Je pense que cela peut encore avoir du sens dans certaines situations. Mais il semble que le flux de code d’autorisation (par défaut dans Discourse) avec PKCE (facultatif dans Discourse) soit la manière la plus recommandée d’utiliser OIDC.
C’est très intéressant - je n’avais pas bien compris PKCE jusqu’à maintenant. D’après ma lecture de la documentation d’Auth0, il semble que (dans certaines configurations) ce flux présente les avantages du flux implicite (pas de secret client) sans aucun des inconvénients.
Est-ce peut-être quelque chose qui peut être fait à la place ? Il semble que ce soit aussi simple que de supprimer le paramètre de secret client du point de terminaison /token.
Et finalement, ma principale préoccupation est simplement d’éliminer l’exigence d’un secret client
diff --git a/plugins/discourse-openid-connect/lib/omniauth_open_id_connect.rb b/plugins/discourse-openid-connect/lib/omniauth_open_id_connect.rb
index 410a88f46dc..e74ee360aae 100644
--- a/plugins/discourse-openid-connect/lib/omniauth_open_id_connect.rb
+++ b/plugins/discourse-openid-connect/lib/omniauth_open_id_connect.rb
@@ -73,6 +73,11 @@ module OmniAuth
)
options[:client_options][:auth_scheme] = :request_body
end
+
+ # Si nous utilisons PKCE _et_ qu'il n'y a pas de client_secret, utilisez le schéma d'authentification request_body.
+ if options[:pkce] && options[:client_secret].empty?
+ options[:client_options][:auth_scheme] = :request_body
+ end
end
def request_phase
L’URI de redirection est configuré dans le panneau de contrôle Azure comme suit :