الانتقال إلى المحتوى الرئيسي
يمكن لـ ClickHouse مصادقة المستخدمين باستخدام JSON Web Tokens ‏(JWTs). وعلى عكس موفّرات المصادقة الخارجية الأخرى مثل LDAP أو Kerberos، فإن المصادقة عبر JWT لا تتحقق من هوية المستخدمين الموجودين مسبقًا. وبدلًا من ذلك، تُنشئ مستخدمين مؤقتين ديناميكيًا من المطالبات المضمّنة في كل رمز مميز. ولا يوجد هؤلاء المستخدمون إلا في الذاكرة، ويحصلون على صلاحيات وصول مشتقة من مطالبات الـ رمز المميز، وتتم إزالتهم تلقائيًا بعد انتهاء صلاحية الـ رمز المميز. وهذا يجعل المصادقة عبر JWT مختلفة جذريًا عن الطرق المعتمدة على password أو الشهادات: فلا توجد عبارة CREATE USER ... IDENTIFIED WITH jwt، وأي محاولة لذلك تؤدي إلى ظهور استثناء. ويُدار مستخدمو JWT بالكامل وفقًا لدورة حياة الـ رمز المميز.

نظرة عامة

يعمل تدفق المصادقة على النحو التالي:
  1. يقدّم عميل رمز JWT موقّعًا عبر إحدى آليات النقل المدعومة (ترويسة HTTP ‏Authorization: Bearer، أو البروتوكول الأصلي عبر TCP، أو الحقل jwt في gRPC).
  2. يتحقق ClickHouse من توقيع الرمز المميز.
  3. يُتحقق من المطالبات المطلوبة (exp, iat, iss, sub, aud).
  4. يُنشأ مستخدم مؤقت في الذاكرة مع صلاحيات وصول مشتقة من مطالبات الرمز المميز clickhouse:grants وclickhouse:roles، ومتقاطعة مع حدّ الصلاحيات.
  5. عند انتهاء صلاحية الرمز المميز، تزيل مهمة جمع البيانات المهملة في الخلفية هذا المستخدم.

مطالبات الرمز المميز

المطالبات المطلوبة

يجب أن يحتوي كل JWT يُقدَّم إلى ClickHouse على المطالبات التالية:
المطالبةالوصف
algخوارزمية التوقيع (مطالبة في الترويسة). القيم المدعومة: HS256 وRS256 وES256.
expوقت انتهاء الصلاحية. يحدّد valid_until للمستخدم المؤقت.
iatوقت الإصدار. يُستخدم لمنع إعادة استخدام الرموز المميزة الأقدم للهوية نفسها.
issالجهة المُصدِرة. يُطابَق مع الجهة المُصدِرة المتوقعة لدى المزوّد.
subالمعرّف. يصبح جزءًا من اسم المستخدم المُنشأ.
audالجمهور المستهدف. يُطابَق مع الجمهور المستهدف المتوقع لدى المزوّد.
تكون مطالبة kid في الترويسة (معرّف المفتاح) مطلوبة أيضًا عند استخدام تحليل المفاتيح المستند إلى JWKS.
يدعم وضع JWKS مفاتيح RSA فقطفي حين أن موفّري المفاتيح الثابتة يقبلون أيًا من HS256 أو RS256 أو ES256، فإن الموفّرين المستندين إلى JWKS لا يقبلون إلا JWKs التي تكون فيها قيمة kty هي RSA (أي الرموز المميزة الموقّعة باستخدام RS256). ولا يمكن التحقق من الرموز المميزة الموقّعة بمفاتيح HMAC (HS256) أو EC (ES256) باستخدام endpoint لـ 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. ويظل هذا المعرّف ثابتًا عبر عمليات تسجيل الدخول. لذا فإن المستخدم الذي يسجّل الدخول عدة مرات باستخدام رموز مميزة مختلفة (ولكن مع issuer وsubject وaudience نفسها) يحصل دائمًا على معرّف UUID نفسه. أما اسم المستخدم فهو غير ثابت. ويُنشأ على النحو التالي:
JWT::<issuer>::<audience>::<subject>::<claims_hash>
يتغيّر الجزء <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::ClickHouse::my-service-id::jane.doe::<claims-hash>';
يمكن العثور على اسم المستخدم ومعرّف UUID لهوية معيّنة في العمودين name وid في system.users ما دام المستخدم نشطًا.
لاحظ أن 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>'
الخيار --jwt لا يمكن استخدامه مع --user. عند تحديد --jwt، يُشتق اسم المستخدم من الرمز المميّز.

واجهة HTTP

أرسل الرمز المميز كـ Bearer token في ترويسة Authorization:
curl -H 'Authorization: Bearer <your_jwt_token>' \
    'https://your-instance.clickhouse.cloud:8443/?query=SELECT+currentUser()'
أرسل دائمًا رموز JWT عبر HTTPS. إن رمز Bearer المُرسَل عبر HTTP غير المشفّر يكون مكشوفًا لأي شخص على مسار الشبكة، ويُعدّ ذلك بمثابة تسريب لبيانات الاعتماد.

تسجيل الدخول باستخدام رمز جهاز 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 في بروتوكول الاتصال بين الخوادم. وتُعيد العقدة البعيدة المصادقة على الرمز بشكل مستقل، وتُنشئ مستخدمًا مؤقتًا خاصًا بها.

استكشاف الأخطاء وإصلاحها

  • لم تُمنح صلاحيات الوصول: قد يفتقر الدور أو المستخدم المشار إليه إلى الامتيازات المطلوبة. تأكد من أن الأدوار المشار إليها في clickhouse:roles موجودة وتتضمن الامتيازات المناسبة.
  • رُفض الرمز المميز: تحقّق من أن iss وaud وخوارزمية التوقيع في الرمز المميز لديك تطابق ما يتوقعه موفّر JWT. إذا كان JWKS مستخدمًا، فتأكد من أن kid الخاص بالرمز المميز يطابق مفتاحًا في مجموعة مفاتيح الموفّر.
  • يختفي المستخدم بين الاستعلامات: يُزال المستخدمون المؤقتون بعد انتهاء صلاحية الرمز المميز. استخدم عميلًا يدعم تحديث الرمز المميز (مثل وضع --login) للجلسات طويلة الأمد.
  • يفشل CREATE USER ... IDENTIFIED WITH jwt: هذا متوقع. لا يمكن إنشاء مستخدمي JWT عبر DDL، إذ تُدار بالكامل من خلال دورة حياة الرمز المميز.
آخر تعديل في ٢٩ يونيو ٢٠٢٦