يمكن لـ ClickHouse مصادقة المستخدمين باستخدام JSON Web Tokens (JWTs). وعلى عكس موفّرات المصادقة الخارجية الأخرى مثل LDAP أو Kerberos، فإن المصادقة عبر JWT لا تتحقق من هوية المستخدمين الموجودين مسبقًا. وبدلًا من ذلك، تُنشئ مستخدمين مؤقتين ديناميكيًا من المطالبات المضمّنة في كل رمز مميز. ولا يوجد هؤلاء المستخدمون إلا في الذاكرة، ويحصلون على صلاحيات وصول مشتقة من مطالبات الـ رمز المميز، وتتم إزالتهم تلقائيًا بعد انتهاء صلاحية الـ رمز المميز.
وهذا يجعل المصادقة عبر JWT مختلفة جذريًا عن الطرق المعتمدة على password أو الشهادات: فلا توجد عبارة CREATE USER ... IDENTIFIED WITH jwt، وأي محاولة لذلك تؤدي إلى ظهور استثناء. ويُدار مستخدمو JWT بالكامل وفقًا لدورة حياة الـ رمز المميز.
نظرة عامة
يعمل تدفق المصادقة على النحو التالي:
- يقدّم عميل رمز JWT موقّعًا عبر إحدى آليات النقل المدعومة (ترويسة HTTP
Authorization: Bearer، أو البروتوكول الأصلي عبر TCP، أو الحقلjwtفي gRPC). - يتحقق ClickHouse من توقيع الرمز المميز.
- يُتحقق من المطالبات المطلوبة (
exp,iat,iss,sub,aud). - يُنشأ مستخدم مؤقت في الذاكرة مع صلاحيات وصول مشتقة من مطالبات الرمز المميز
clickhouse:grantsوclickhouse:roles، ومتقاطعة مع حدّ الصلاحيات. - عند انتهاء صلاحية الرمز المميز، تزيل مهمة جمع البيانات المهملة في الخلفية هذا المستخدم.
مطالبات الرمز المميز
المطالبات المطلوبة
يجب أن يحتوي كل JWT يُقدَّم إلى ClickHouse على المطالبات التالية:
| المطالبة | الوصف |
|---|---|
alg |
خوارزمية التوقيع (مطالبة في الترويسة). القيمة المدعومة: RS256. بدءًا من الإصدار 26.8، تُدعم أيضًا خوارزميات EC وهي ES256 وES384 وES512. |
exp |
وقت انتهاء الصلاحية. يحدّد valid_until للمستخدم المؤقت. |
iat |
وقت الإصدار. يُستخدم لمنع إعادة استخدام الرموز المميزة الأقدم للهوية نفسها. |
iss |
الجهة المُصدِرة. يُطابَق مع الجهة المُصدِرة المتوقعة لدى المزوّد. |
sub |
المعرّف. يصبح جزءًا من اسم المستخدم المُنشأ. |
aud |
الجمهور المستهدف. يُطابَق مع الجمهور المستهدف المتوقع لدى المزوّد. |
تكون مطالبة kid في الترويسة (معرّف المفتاح) مطلوبة أيضًا عند استخدام تحليل المفاتيح المستند إلى JWKS.
مطالبات أخرى معترف بها
| المطالبة | الوصف |
|---|---|
nbf |
وقت "ليس قبل". هذه المطالبة ليست مطلوبة، ولكن إذا كانت موجودة، فسيتم رفض الرموز المميزة قبل هذا الوقت. |
jti |
محجوزة. تُقبل في الرموز المميزة، ولكن لا يُتحقق منها أو تُستخدم حاليًا. |
المطالبات الاختيارية
| المطالبة | الاسم الافتراضي | الوصف |
|---|---|---|
| الامتيازات | clickhouse:grants |
مصفوفة JSON تضم مقاطع من عبارة SQL GRANT، مثل ["SELECT ON db.*", "INSERT ON db.table1"]. ويُفسَّر كل عنصر على أنه متن عبارة GRANT. |
| الأدوار | clickhouse:roles |
مصفوفة JSON لأسماء الأدوار المراد إسنادها، مثل ["analyst", "reader"]. |
| يمكن إعادة تعيين أسماء المطالبات الافتراضية إلى أسماء مطالبات مخصّصة إذا كان موفّر الهوية لديك يستخدم اصطلاحات تسمية مختلفة. |
مثال على رأس الرمز المميز وحمولته
{
"alg": "RS256",
"kid": "my-key-id"
}{
"iss": "https://idp.example.com",
"sub": "jane.doe",
"aud": "my-clickhouse-cluster",
"exp": 1719504000,
"iat": 1719500400,
"clickhouse:grants": ["SELECT ON analytics.*", "INSERT ON analytics.events"],
"clickhouse:roles": ["analyst"]
}سلوك المستخدم المؤقت
يختلف مستخدمو JWT عن مستخدمي ClickHouse العاديين في عدة نواحٍ مهمة.
الهوية والتسمية
يتلقى كل مستخدم JWT معرّف UUID حتميًا يُحتسب من مطالبات iss وsub وaud. ويظل هذا المعرّف ثابتًا عبر عمليات تسجيل الدخول. لذا فإن المستخدم الذي يسجّل الدخول عدة مرات باستخدام رموز مميزة مختلفة (ولكن مع الجهة المُصدِرة والمعرّف والجمهور المستهدف نفسها) يحصل دائمًا على معرّف UUID نفسه.
أما اسم المستخدم فهو غير ثابت. ويُنشأ على النحو التالي:
JWT::<subject>::<claims_hash>يشير <claims_hash> إلى قيمة تجزئة مشتقة من مطالبات iss وsub وaud إلى جانب المطالبتين clickhouse:roles وclickhouse:grants. ولا تدخل المطالبتان iss وaud إلا من خلال هذه القيمة؛ إذ لم تعودا تُدرجان مباشرةً ضمن بادئة اسم المستخدم الظاهرة. وهذا يُبقي الاسم موجزًا وسهل القراءة عندما تكون عناوين URL الخاصة بـ IdP في iss/aud طويلة وغير واضحة (على سبيل المثال، Microsoft Entra أو Okta)، مع ضمان أن الثلاثيات المختلفة (iss, sub, aud) ومجموعات clickhouse:roles / clickhouse:grants المختلفة تُنتِج أسماء مختلفة وثابتة. أما المطالبات التي لا تدخل في حساب قيمة التجزئة (مثل iat أو exp أو nbf أو المطالبات المخصصة غير المرتبطة) فلا تغيّر اسم المستخدم.
يتغيّر الجزء <claims_hash> كلما تغيّرت المطالبات clickhouse:roles أو clickhouse:grants. وهذا يعني أن الرموز المميّزة ذات مجموعات الأدوار أو الامتيازات المختلفة تُنتِج أسماء مستخدمين مختلفة حتى للهوية نفسها.
صلاحيات الوصول
تُحتسب صلاحيات الوصول الفعلية على النحو التالي:
effective_rights = permission_limit ∩ (token_grants ∪ token_roles)حيث إن permission_limit هي مجموعة حقوق الوصول التي يمتلكها دور مرجعي أو مستخدم مُعدّ ليكون الحد الأعلى. وأي حقوق يطلبها الرمز المميز وتتجاوز هذا الحد تُسقَط بصمت.
حداثة الرمز المميز
يتتبّع ClickHouse مطالبة iat (وقت الإصدار) لأحدث رمز مميز تمت مصادقته لكل هوية مستقرة. وإذا قُدِّم رمز مميز بقيمة iat تساوي القيمة المخزنة أو تسبقها، يعيد الخادم استخدام المستخدم المؤقت الحالي من دون إعادة تقييم المطالبات. ويمنع ذلك الرموز المميزة الأقدم من تقليص أذونات المستخدم.
دورة الحياة وجمع البيانات المهملة
يتم إنشاء المستخدمين المؤقتين عند مصادقة الرمز المميز لأول مرة، ثم تُزيلهم مهمة جمع البيانات المهملة في الخلفية بعد انقضاء valid_until (المشتق من exp). ويتم التحكم في الفاصل الزمني لـ GC بواسطة المعلَمة gc_interval (الافتراضي: 5 دقائق).
بين مرات تشغيل GC، قد يظل المستخدمون منتهو الصلاحية ظاهرين في system.users، لكن لن يعودوا قادرين على المصادقة.
تعيينات صلاحيات الوصول الدائمة
نظرًا لأن معرّف UUID ثابت، يمكنك إسناد ملفات تعريف الإعدادات، والحصص، وسياسات الصفوف، وسياسات إخفاء الأعمدة إلى مستخدم JWT باستخدام عبارات SQL. وتظل هذه التعيينات محفوظة في مخزن التحكم في الوصول (على القرص أو في ZooKeeper)، وتبقى سارية بعد انتهاء صلاحية الرمز المميز وإعادة المصادقة.
استخدم اسم المستخدم الحالي للإشارة إلى المستخدم:
ALTER SETTINGS PROFILE my_profile ADD TO 'JWT::jane.doe::<claims_hash>';لاحظ أن ALTER USER لا يعمل مباشرةً مع مستخدمي JWT، لأنهم للقراءة فقط. لإسناد ملفات تعريف الإعدادات أو الحصص أو السياسات، استخدم عبارات ALTER SETTINGS PROFILE أو ALTER QUOTA أو ALTER ROW POLICY كما هو موضح أعلاه.
الاختلافات عن المستخدمين العاديين
| الميزة | مستخدمو JWT | المستخدمون العاديون |
|---|---|---|
| الإنشاء | تلقائي من مطالبات الرمز | عبارة CREATE USER |
| التخزين | في الذاكرة فقط (مؤقت) | القرص أو ZooKeeper أو ملف الإعدادات |
CREATE USER ... IDENTIFIED WITH jwt |
غير مدعوم (يؤدي إلى استثناء) | جميع أنواع المصادقة الأخرى مدعومة |
ALTER USER / DROP USER |
غير مدعوم | مدعوم |
| النسخ الاحتياطي والاستعادة | غير مشمولين | مشمولان |
| اسم المستخدم | يُنشأ تلقائيًا، وغير ثابت | يختاره المسؤول، وثابت |
| معرّف UUID | يُشتق حتميًا من iss+sub+aud |
عشوائي عند الإنشاء |
| مدة الصلاحية | مقيّدة بـ exp الخاص بالرمز |
حتى يُحذف صراحةً |
| صلاحيات الوصول | مشتقة من مطالبات الرمز، ومقيّدة بحدّ الصلاحيات | تُمنح صراحةً عبر GRANT |
| قيود المضيف | تهيئة الشبكة الخاصة بكل موفّر | عبارة HOST لكل مستخدم |
| ملفات تعريف الإعدادات | يمكن إسنادها بواسطة معرّف UUID (بشكل دائم) | قابلة للتهيئة مباشرةً |
| الحصص وسياسات الصفوف | يمكن إسنادها بواسطة معرّف UUID (بشكل دائم) | قابلة للتهيئة مباشرةً |
| الأدوار الافتراضية | غير قابلة للتهيئة | قابلة للتهيئة |
طرق العرض SQL SECURITY DEFINER
عندما ينشئ مستخدم JWT مؤقت طريقة عرض باستخدام SQL SECURITY DEFINER، ينشئ الخادم تلقائيًا نسخة ظل دائمة من هذا المستخدم لتكون مُعرِّف طريقة العرض. ويتميّز هذا المستخدم الظل بما يلي:
- يحمل الاسم
<original_jwt_username>:definer - لديه
NO_AUTHENTICATION(ولا يمكن استخدامه لتسجيل الدخول) - يحتفظ بحقوق الوصول نفسها التي كانت لدى مستخدم JWT الأصلي وقت إنشاء طريقة العرض
وهذا يضمن استمرار طريقة العرض في العمل بعد انتهاء صلاحية رمز المستخدم المؤقت وإزالة المستخدم الأصلي عبر جمع المهملات.
استخدام العميل البرمجي
تمرير رمز مميز مباشرةً
استخدم الخيار --jwt مع clickhouse-client للمصادقة باستخدام رمز مميز تم الحصول عليه مسبقًا:
clickhouse-client --host your-instance.clickhouse.cloud --secure --jwt '<your_jwt_token>'واجهة HTTP
أرسل الرمز المميز كـ Bearer token في ترويسة Authorization:
curl -H 'Authorization: Bearer <your_jwt_token>' \
'https://your-instance.clickhouse.cloud:8443/?query=SELECT+currentUser()'تسجيل الدخول باستخدام رمز جهاز OAuth2
يدعم clickhouse-client مسار رمز جهاز OAuth2 التفاعلي عبر الخيار --login. بالنسبة إلى نقاط النهاية في ClickHouse Cloud، يُجري العميل تلقائيًا عملية تبادل الرموز المميزة للحصول على JWT خاص بـ ClickHouse. تُحدَّث الرموز المميزة تلقائيًا أثناء الجلسة. وعند الحصول على رمز مميز جديد، يعيد العميل الاتصال تلقائيًا.
clickhouse-client --host your-instance.clickhouse.cloud --loginمُصادِق JWT المضمّن في ClickHouse Cloud
تأتي كل خدمة في ClickHouse Cloud مع مُصادِق JWT مُعرَّف مسبقًا يُستخدم في SQL Console ومع تدفّق --login في clickhouse-client. يُضبط هذا المُصادِق على النحو التالي:
| المَعلمة | القيمة |
|---|---|
iss (issuer) |
ClickHouse |
aud (audience) |
معرّف UUID الخاص بالخدمة (ويظهر في عنوان URL لوحدة تحكم Cloud) |
sub (subject) |
عنوان البريد الإلكتروني لحسابك في ClickHouse Cloud |
يحتوي المُصادِق المضمّن على حدٍّ للصلاحيات مضبوط على الدور default_role والمستخدم default. وهذا يعني أن الصلاحيات الفعلية لأي مستخدم JWT تُقاطع مع الصلاحيات الممنوحة لهذين الكيانين، لذا لا يمكن لأي رمز JWT مطلقًا رفع الامتيازات إلى ما يتجاوز المسموح به لكل من default_role وdefault.
لا تحتاج إلى تهيئة أي شيء لاستخدام هذا المُصادِق. إذ يُوفَّر تلقائيًا عند إنشاء الخدمة.
تمكين المصادقة باستخدام JWT لخدمتك
المصادقة باستخدام JWT باستخدام موفّر هوية مخصّص متوفرة في خطة Enterprise. للترقية، انتقل إلى صفحة الخطط في Cloud Console.
بالإضافة إلى المُصادِق المضمّن، يمكنك تهيئة خدمة ClickHouse Cloud لقبول رموز مميزة JWT الصادرة عن موفّر الهوية الخاص بك، مثل Microsoft Entra أو Okta. هذه ميزة Beta متاحة ضمن خطة Enterprise للخدمات التي تعمل بإصدار ClickHouse 26.4 أو أحدث. يمكنك تهيئتها بنفسك من وحدة تحكم Cloud ضمن الإعدادات ← الأمان ← المصادقة باستخدام JWT — راجع إعداد المصادقة باستخدام JWT للحصول على إرشادات خطوة بخطوة. يُعرَّف كل موفّر بما يلي:
| المَعلمة | الوصف |
|---|---|
| الاسم | اسم فريد للموفّر على الخدمة. |
| الجهة المُصدِرة | قيمة مطالبة iss في الرموز المميزة الصادرة عن موفّر الهوية الخاص بك، وتكون عادةً عنوان URL الخاص بالموفّر، مثل https://your-tenant.okta.com. يرفض ClickHouse الرموز المميزة التي لا تتطابق جهتها المُصدِرة مع هذه القيمة. |
| الجمهور المستهدف | قيمة مطالبة aud التي يضيفها موفّر الهوية الخاص بك إلى الرموز المميزة المخصصة لهذه الخدمة. يرفض ClickHouse الرموز المميزة الصادرة لجمهور مستهدف مختلف. |
| URL لـ JWKS | نقطة نهاية HTTPS التي ينشر فيها موفّر الهوية الخاص بك مجموعة مفاتيح الويب JSON الخاصة به، مثل https://idp.example.com/.well-known/jwks.json. يجلب ClickHouse المفاتيح العامة من نقطة النهاية هذه للتحقق من توقيعات الرموز المميزة. يعمل التحقق من JWKS مع مفاتيح RSA (RS256) وكذلك، بدءًا من الإصدار 26.8، مع مفاتيح EC على المنحنيات P-256 وP-384 وP-521 (ES256 وES384 وES512)، كما هو موضح في المطالبات المطلوبة. |
| مطالبة الأدوار (اختيارية) | اسم مطالبة الرمز المميز التي تتضمن أدوار ClickHouse للمستخدم المؤقت. اتركها فارغة لاستخدام اسم المطالبة الافتراضي clickhouse:roles. يجب أن تحتوي المطالبة على مصفوفة JSON من أسماء الأدوار، مثل ["analyst", "reader"]. |
الاتصال بين الخوادم
عندما يُعاد توجيه الاستعلام إلى сегмент أو نسخة متماثلة أخرى، يُضمَّن رمز JWT في بروتوكول الاتصال بين الخوادم. وتُعيد العقدة البعيدة المصادقة على الرمز بشكل مستقل، وتُنشئ مستخدمًا مؤقتًا خاصًا بها.
استكشاف الأخطاء وإصلاحها
- لم تُمنح صلاحيات الوصول: قد يفتقر الدور أو المستخدم المشار إليه إلى الامتيازات المطلوبة. تأكد من أن الأدوار المشار إليها في
clickhouse:rolesموجودة وتتضمن الامتيازات المناسبة. - رُفض الرمز المميز: تحقّق من أن
issوaudوخوارزمية التوقيع في الرمز المميز لديك تطابق ما يتوقعه موفّر JWT. إذا كان JWKS مستخدمًا، فتأكد من أنkidالخاص بالرمز المميز يطابق مفتاحًا في مجموعة مفاتيح الموفّر. - يختفي المستخدم بين الاستعلامات: يُزال المستخدمون المؤقتون بعد انتهاء صلاحية الرمز المميز. استخدم عميلًا يدعم تحديث الرمز المميز (مثل وضع
--login) للجلسات طويلة الأمد. - يفشل
CREATE USER ... IDENTIFIED WITH jwt: هذا متوقع. لا يمكن إنشاء مستخدمي JWT عبر DDL، إذ تُدار بالكامل من خلال دورة حياة الرمز المميز.