Browse Source

Fixes #5485 - Add PKCE support to OpenID Connect.

Co-authored-by: Florian Liebe <fl@zammad.com>
Co-authored-by: Dominik Klein <dk@zammad.com>
Florian Liebe 1 month ago
parent
commit
14ebad4fce

+ 34 - 0
config/initializers/omniauth_openid_connect.rb

@@ -0,0 +1,34 @@
+# Copyright (C) 2012-2025 Zammad Foundation, https://zammad-foundation.org/
+
+require 'omniauth/openid_connect'
+
+# Monkey patch to support more different token endpoints. Can be removed when this PR is merged:
+# https://github.com/omniauth/omniauth_openid_connect/pull/192
+module OmniAuth
+  module Strategies
+    class OpenIDConnect
+      def access_token
+        return @access_token if @access_token
+
+        token_request_params = {
+          scope:              (options.scope if options.send_scope_to_token_endpoint),
+          client_auth_method: options.client_auth_method,
+        }
+
+        token_request_params[:code_verifier] = params['code_verifier'] || session.delete('omniauth.pkce.verifier') if options.pkce
+
+        if configured_response_type == 'code'
+          token_request_params[:grant_type] = :authorization_code
+          token_request_params[:code] = authorization_code
+          token_request_params[:redirect_uri] = redirect_uri
+          token_request_params[:client_id] = client_options.identifier
+        end
+
+        @access_token = client.access_token!(token_request_params)
+        verify_id_token!(@access_token.id_token) if configured_response_type == 'code'
+
+        @access_token
+      end
+    end
+  end
+end

+ 35 - 0
db/migrate/20250210105644_open_id_connect_pkce.rb

@@ -0,0 +1,35 @@
+# Copyright (C) 2012-2025 Zammad Foundation, https://zammad-foundation.org/
+
+class OpenIdConnectPkce < ActiveRecord::Migration[7.2]
+  def change
+    # return if it's a new setup
+    return if !Setting.exists?(name: 'system_init_done')
+
+    setting = Setting.find_by(name: 'auth_openid_connect_credentials')
+    return if setting.nil?
+
+    setting.options[:form].push({
+                                  display:   'PKCE',
+                                  null:      true,
+                                  default:   true,
+                                  name:      'pkce',
+                                  tag:       'select',
+                                  options:   {
+                                    true  => 'yes',
+                                    false => 'no',
+                                  },
+                                  translate: true,
+                                  help:      'Proof Key for Code Exchange is currently only supporting SHA256 as code challenge method.',
+                                })
+
+    setting.options[:form].push({
+                                  display:  'Your callback URL',
+                                  null:     true,
+                                  name:     'callback_url',
+                                  tag:      'auth_provider',
+                                  provider: 'auth_openid_connect',
+                                })
+
+    setting.save!
+  end
+end

+ 20 - 0
db/seeds/settings.rb

@@ -2102,6 +2102,26 @@ Setting.create_if_not_exists(
         placeholder: 'openid email profile',
         help:        __('Scopes that are included, separated by a single space character. If unset, "openid email profile" is used.'),
       },
+      {
+        display:   __('PKCE'),
+        null:      true,
+        default:   true,
+        name:      'pkce',
+        tag:       'select',
+        options:   {
+          true  => 'yes',
+          false => 'no',
+        },
+        translate: true,
+        help:      __('Proof Key for Code Exchange is currently only supporting SHA256 as code challenge method.'),
+      },
+      {
+        display:  __('Your callback URL'),
+        null:     true,
+        name:     'callback_url',
+        tag:      'auth_provider',
+        provider: 'auth_openid_connect',
+      },
     ],
   },
   state:       {},

File diff suppressed because it is too large
+ 162 - 162
i18n/zammad.pot


+ 1 - 0
lib/omni_auth/strategies/oidc_database.rb

@@ -20,6 +20,7 @@ class OmniAuth::Strategies::OidcDatabase < OmniAuth::Strategies::OpenIDConnect
     auth_openid_connect_credentials.compact_blank.merge(
       discovery:      true,
       response_type:  :code,
+      pkce:           ActiveModel::Type::Boolean.new.cast(auth_openid_connect_credentials['pkce']),
       client_options:,
     )
   end

Some files were not shown because too many files changed in this diff